首页 > 解决方案 > 将偶数相除,直到结果为奇数

问题描述

我试图将一个数字除以 2,如果它是偶数,直到每个操作返回一个奇数,例如,将 16 除以 2 返回 8,然后除以 2 返回 4,直到它达到 2。

我尝试过使用递归,但它的性能非常糟糕,所以我写了下面的代码......问题是它只划分一次:

public int InchFraction(int value)
{
    for (int i = 0; i < value; i++)
    {
        if (value % 2 == 0)
        {
            value = value / 2;
            return value;
        }
    }
    return value;
}

InchFraction(16) //它返回 8

标签: c#mathnumbers

解决方案


public int InchFraction(int value)
{
    while (value % 2 == 0) 
        value /= 2;
    return value;
}

或者因为你正在尝试优化,试试这个

private static int countDivOps = 0;
private static int countCalls = 0;
static ulong M2(ulong v, int p = 32)
{
  var d = 1UL << p;
  countCalls++;
  while (v % d == 0) 
  {
    v /= d;
    countDivOps++;
  }
  return d == 2 ? v : M2(v, p / 2);
}
static void Main(string[] args)
{
  var v = 0x1204000000000000ul;
  var rv = M2(v);
  Console.WriteLine($"{v} reduces to {rv}(0x{rv:X}) in {countCalls} calls after (2x) {countDivOps} division operations");

这不漂亮,我让你玩你的调试器,看看它在做什么,但 FWIW 输出是......

1298162592589545472 (0x1204000000000000) reduces to 1153(0x481) in 6 calls after (2x) 3 division operations

请注意,代码的成本不仅仅与除法运算和调用有关,这只是为了说明您如何处理此类问题。


推荐阅读