[英]Get the children of a given parent
我有一組數字: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#)。
它不適用於很大的數字的原因是因為您使用的是精度有限(大約16位數字)的double
精度數據類型。
除了使用Math.Pow
和Math.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 << i
您將第一位移到2的i次方。您可以修改上面的代碼,使其與您的代碼更相似,並且效率更高,而不是迭代i
, parentMask
移動parentMask
的位,但是隨后您必須知道負數會發生什么,以及邏輯移位與算術移位有何不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.