與整數實現時,你總是可以從相當於數學公式開始:
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
爲什麼你這樣聲明函數參數? –