部分或包裹的乘法 - 任何人都可以识别这个功能吗?

时间:2009-04-28 19:45:58

标签: c algorithm math puzzle

我希望能够洞察看起来像是部分乘法的东西。

#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的情况怎么样?

任何指向更多信息的链接都会有所帮助..

4 个答案:

答案 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的上半部分和下半部分混合在一起。