与整数实现时,你总是可以从相当于数学公式开始:
R = 2 -30 *(X * SQRT(2 + 2 * Y/X))
甲典型的32位处理器应该允许您访问64/32 - > 32分频器,并在两个寄存器中提供输入。这个除法可以用来计算* y/x。您的编程语言可能会或不会让您访问它。在生成涉及64位中间结果的计算的32位代码时,不要低估优化编译器的技能。
类似地,典型的32位处理器应该为“x * ...”提供一个32 * 32-> 64的乘法,结果在两个寄存器中。
最后乘以2 -30相当于移位和控制32 * 32-> 64乘法结果的两个寄存器。
GCC almost管理仅使用32位指令来产生简单的代码,但它丢弃该球在一个点,并调用一个外部多精度除法功能:
#include <stdint.h>
uint32_t integer_sqrt(uint32_t);
/*@ requires x >= y; */
uint32_t hypot(uint32_t x, uint32_t y){
return integer_sqrt(0x40000000 + (uint32_t) ((uint64_t)y * 0x40000000/x)) * (uint64_t) x/0x40000000 ;
}
32位组件结果:
hypot:
pushl %edi
pushl %esi
xorl %edi, %edi
pushl %ebx
movl 16(%esp), %ebx
movl %edi, %edx
xorl %edi, %edi
subl $16, %esp
movl 36(%esp), %esi
pushl %edi
pushl %ebx
shldl $30, %esi, %edx
movl %esi, %eax
sall $30, %eax
pushl %edx
pushl %eax
call __udivdi3
addl $20, %esp
addl $1073741824, %eax
pushl %eax
call integer_sqrt
mull %ebx
addl $16, %esp
popl %ebx
popl %esi
shrdl $30, %edx, %eax
popl %edi
ret
编辑:
如果你只想使用32 * 32> 32乘法,你必须计算N = LOG 2(x)和,如果N> 15,normaliz ex和由N-15它们右移Y(移位相同的量留下的最终结果),实际上实现下式:
R = 2 N-15 * SQRT((X/2 Ñ -15) +(Y/2 N-15))
如果N≤1,只要使用通常的公式R = SQRT(X + Y )
你改变什么,问题是现在约64位整数?! –
@PascalCuoq它从来就不是32位的,它是关于溢出的,而32位只是一个例子。 – user22698
为什么你这样声明函数参数? –