【问题标题】:Get the children of a given parent获取给定父母的孩子
【发布时间】:2013-06-04 11:30:46
【问题描述】:

我有一组数字:1、2、4、8、16、32、64等

现在给定一个数字,比如说 44,我必须确定它有 32、8 和 4 个孩子。 (32 + 8 + 4 = 44)

到目前为止,我有以下代码:

   public static long[] GetBTreeChildren(long? parentMask)
    {            
        var branches = new List<long>();
        if (parentMask == null) return branches.ToArray();

        double currentValue = (double)parentMask;            

        while (currentValue > 0D)
        {
            double power = Math.Floor(Math.Log(currentValue, 2.0D));

            double exponentResult = Math.Pow(2, power);

            branches.Add((long)exponentResult);

            currentValue -= exponentResult;
        }

        return branches.ToArray();
    }

但是当给定的数字非常大(例如 36028797018963967)时,上面的代码不起作用

我正在使用 VS2012 (C#)。

【问题讨论】:

  • 你尝试过 BigInteger 吗?
  • c#中没有BigInteger

标签: c# binary-tree


【解决方案1】:

它不适用于非常大的数字的原因是因为您使用的是 double 数据类型,这些数据类型的精度有限(大约 16 位)。

无需使用Math.PowMath.Log,您所需的一切都可以通过简单、极其高效的按位运算来完成。

public static long[] GetBTreeChildren(long? parentMask)
{            
    var branches = new List<long>();
    if (parentMask == null) return branches.ToArray();

    for(int i = 0; i < 63; ++i)
    {
        if( (parentMask & (1L << i)) != 0)
            branches.Add(1L << i);
    }            

    return branches.ToArray();
}

基本上,每个位已经是 2 的幂,这就是您要寻找的。通过执行(long) 1 &lt;&lt; i,您将第一位移动到 2 的第 i 次幂。您可以调整上面的代码,使其与您的代码更相似,并且效率更高,而不是迭代 i,只需移动 @ 987654327@ 的位在右边,但是你必须知道负数会发生什么,以及逻辑移位与算术移位有何不同。

【讨论】:

  • 天啊,它就像一个魅力!我必须学习按位运算符。非常感谢!你救了我的命..lol
猜你喜欢
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多