我使用"De Bruijn"算法来发现大数(最多64位)的二进制位数.
例如:
我发现使用基于De Bruijn的表查找让我有能力比传统方式(功率,方形......)计算x100倍.
根据该网站,2 ^ 6具有用于计算64位数的表.这将是c#中暴露的表
static readonly int[] MultiplyDeBruijnBitPosition2 = new int[64]
{
0,1,2,4,8,17,34,5,11,23,47,31,63,62,61,59,
55,46,29,58,53,43,22,44,24,49,35,7,15,30,60,57,
51,38,12,25,50,36,9,18,37,10,21,42,20,41,19,39,
14,28,56,48,33,3,6,13,27,54,45,26,52,40,16,32
};
Run Code Online (Sandbox Code Playgroud)
(我不知道我是否正确地从该网站带来了桌子)然后,根据R ..评论这里.我应该使用它来使用带有输入uint64号的表.
public static int GetLog2_DeBruijn(ulong v)
{
return MultiplyDeBruijnBitPosition2[(ulong)(v * 0x022fdd63cc95386dull) >> 58];
}
Run Code Online (Sandbox Code Playgroud)
但是c#编译器不允许我使用" 0x022fdd63cc95386dull ",因为它溢出了64位.我必须使用" 0x022fdd63cc95386d "代替.
使用这些代码.问题是我没有得到给定输入的正确结果.
例如,做1.000.000计算的数字:17012389719861204799(使用64位)这是结果:
我试图理解"De Bruijn"是如何工作的,我该如何解决这个问题并为c#创建一个最终代码来计算多达64位的数字.
UDPATE和不同解决方案的基准
我正在寻找最快的算法来获得二进制数字的位数,无符号给定数量的64位在c#中(称为ulong).
例如:
传统的2和平方功率非常慢.只需10000次计算就需要1500ms才能得到答案.(100M计算需要数小时).
在这里,Niklas B., …
首先,我没有商务帐户,所以如果这是问题,请告诉我,因为几乎不可能在他们的官方网站上找到Paypal Express Checkout的重新获得.
我的API代码是:
$requestParams = array(
'METHOD' => $method,
'VERSION' => $this -> _version,
'USER' => $PayPalApiUsername,
'PWD' => $PayPalApiPassword,
'SIGNATURE' => $PayPalApiSignature
);
$request = array_merge($requestParams, $params);
//$params is bringed from other php.
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL ,'https://api-3t.paypal.com/nvp');
curl_setopt($ch,CURLOPT_VERBOSE ,1);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER ,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST ,false);
curl_setopt($ch,CURLOPT_RETURNTRANSFER ,1);
curl_setopt($ch,CURLOPT_HTTPGET ,true);
curl_setopt($ch,CURLOPT_POSTFIELDS ,$request);
$response = curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)
然后,直到这里(我认为)好了.但是做一些检查这是我用$ request发送的:
$request: array(16) {
["METHOD"]=>
string(18) "SetExpressCheckout"
["VERSION"]=>
string(4) "97.0"
["USER"]=>
string(27) "xxx_api1.example.com"
["PWD"]=>
string(16) "yyyyyyyyyyyyyyyy"
["SIGNATURE"]=>
string(56) "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
["RETURNURL"]=>
string(50) "http%3A%2F%2Fwww.website.com%2Fcontinue.php"
["CANCELURL"]=>
string(53) …
Run Code Online (Sandbox Code Playgroud) 使用stats()或仅在计算数据库大小时会出现问题。在Windows 7,本地主机中使用postgresql。
执行此操作后的问题是:
"could not stat file "base/17436/119145": Permission denied"
Run Code Online (Sandbox Code Playgroud)
我花了很多时间尝试解决此问题,直到我意识到真正的问题所在。
所以我要回答自己。
我试图在任何地方找到解决方案.我的请求是找到一个非常快速的算法代码,以获得无符号64位积分器(ulong)的二进制表示中的位数.
例如:
127 = 7 binary digits.
153 = 8 binary digits.
Run Code Online (Sandbox Code Playgroud)
我现在找到了两种方法来获得这个.
两种方式都很好,但是当数量很大时,计算时间太长.在10.000.000.000(10亿)之后,你必须计算花费的时间,而不是毫秒,这对于其余代码的性能来说是如此糟糕.
非常感谢并且对于演示文稿感到抱歉,这是用手机写的,我没有所有的工具来把这个更好的和正确的.
编辑1
通过深入了解Bithacks网站并将速度作为首要任务.我想我将使用具有De Bruijn序列实现的Lookup表方法.
正如我在这里找到的:具有2 ^ 6的64位的查找表应该是这样的.
static readonly int[] MultiplyDeBruijnBitPosition2 = new int[64]
{
0,1,2,4,8,17,34,5,11,23,47,31,63,62,61,59,
55,46,29,58,53,43,22,44,24,49,35,7,15,30,60,57,
51,38,12,25,50,36,9,18,37,10,21,42,20,41,19,39,
14,28,56,48,33,3,6,13,27,54,45,26,52,40,16,32
};
Run Code Online (Sandbox Code Playgroud)
在此基础上,用户"R .."从#1,他让自己的paramether,在C#应该是这样的:
public static int GetLog2_DeBruijn(ulong v)
{
return MultiplyDeBruijnBitPosition2[(ulong)(v * 0x022fdd63cc95386dull) >> 58];
}
Run Code Online (Sandbox Code Playgroud)
结果真的很快但错了,我不确切知道为什么.PD:正如您所看到的"0x022fdd63cc95386dull"是128位,C#的接受代码是"0x022fdd63cc95386d".与此处的查找表中显示的相同.
我想因为我不能在C#中使用"0x022fdd63cc95386dull",我必须使用另一个数字而不是58,或者可能是一个完全不同的十六进制64位乘数.
到目前为止,输入的数字为:17012389719861204799(使用了64位)
c# ×2
performance ×2
algorithm ×1
binary ×1
count ×1
counter ×1
denied ×1
digit ×1
paypal ×1
permissions ×1
postgresql ×1
stat ×1
ulong ×1