我希望能够洞察看起来像是部分乘法的东西。
#define LOW(x) ((x)&0xffffffff)
#define HIGH(x) ((x)>>32)
unsigned long long NotMultiply(unsigned long long x, unsigned long long y)
{
return HIGH(x)*HIGH(y) + LOW(x)*LOW(y);
}
此函数重复多次,如下所示:
unsigned long long DoBusyWork( unsigned long long x, unsigned long long y, int n)
{
while (n--)
x = NotMultiply(x,y);
return x;
}
是否有计算此结果的快捷方式?
那个x == y的情况怎么样?
任何指向更多信息的链接都会有所帮助..
答案 0 :(得分:1)
看起来像一个奇怪的哈希计算。它取两个数字的低32位,乘以它们,取较高的32位(将它们移动到较低的位置)并乘以它们,并返回它的总和。
我认为你不能让它更简单,但可能更快。如果再次返回相同的值,则可以中断while循环。
unsigned long long DoBusyWork( unsigned long long x, unsigned long long y, int n)
{
long long previousX = x;
while (n--)
{
x = NotMultiply(x,y);
if (x == previousX) break;
previousX = x;
}
return x;
}
我不知道是否很有可能提前完成循环。
答案 1 :(得分:1)
DoBusyWork(正如@RBerteig建议的那样,名称是一个红色标志)可能是强制编译器不优化忙循环的一种方法。
这些愚蠢的编译器变得如此聪明,以至于有时他们会决定,“哦!你不需要在那里循环!我看到你想要计算的东西!”尽管你作为程序员真正感兴趣。
答案 2 :(得分:1)
这是随机数生成器的早期形式,通常用于小型机和小型主机。电话可能看起来像这样:
unsigned long long seedold = 0xA5A5A5A5A5A5A5A5;
unsigned long long seednew = 0X5A5A5A5A5A5A5A5A;
unsigned long long lltmp;
int finetune;
通过计时键盘或类似的真正随机但慢的方法随机化finetune
,
然后像这样打电话:
lltmp = DoBusyWork( seedold, seednew, finetune );
seedold = seednew;
seednew = lltmp;
随后通过这样称呼它作为PRNG:
lltmp = DoBusyWork( seedold, seednew, 1 );
seedold = seednew;
seednew = lltmp;
使用seednew作为PRN。
冯·诺伊曼曾经主张对“蒙特卡罗”测试应用进行这种计算,但后来当他更多地了解分析PRNG的输出时改变了主意。-Al。
答案 3 :(得分:0)
LOW尝试仅占用底部的32位。高电平将接下来的32位向下移动32位。整个NotMultiply例程尝试将x和y的底部32位加在一起,并将它们添加到前32位。 DoBusyWork n 次。
如果x == y,则得到HIGH(x)²+ LOW(x)²。
但是,我不知道他们为什么要这样做。它将x和y的上半部分和下半部分混合在一起。