我創建了一個應用程序來計算64位範圍內的素數,所以當我試圖使用sqrt
函數從math.h
計算64位數的平方根時我發現答案並不準確例如,當輸入爲~0ull
答案應該是~0u
但一個我得到的是0x100000000
這是不正確的,所以我決定創建我自己的版本使用匯編x86的語言,看看這是一個錯誤,這是我的功能:這是一個在sqrt函數中的錯誤
inline unsigned prime_isqrt(unsigned long long value)
{
const unsigned one = 1;
const unsigned two = 2;
__asm
{
test dword ptr [value+4], 0x80000000
jz ZERO
mov eax, dword ptr [value]
mov ecx, dword ptr [value + 4]
shrd eax, ecx, 1
shr ecx, 1
mov dword ptr [value],eax
mov dword ptr [value+4],ecx
fild value
fimul two
fiadd one
jmp REST
ZERO:
fild value
REST:
fsqrt
fisttp value
mov eax, dword ptr [value]
}
}
輸入是奇數,以獲取其平方根。當我測試我的功能相同的輸入結果是一樣的。
什麼,我不明白的是爲什麼圓的結果,或者這些功能要具體爲什麼sqrt
指令一輪結果如何呢?
謝謝你,所以我可以用低32位計算它的平方根 - 稱之爲(a) - 然後從64位數中減去低32位並得到該數的平方根 - 稱之爲(b) - 現在全部我需要做的就是(a)乘以(b),我們就完成了。 –
@Muhammadalaa:呃,沒有。 64位可以用數學方式寫成(H * 2^32 + L),其中H和L各爲32位。你聲明'sqrt(H * 2^32 + L)'='sqrt(L)* sqrt(H * 2^32)'。事實並非如此。但是,您可以將其計算爲sqrt(H)* sqrt(2^32 + L/H)'。 – MSalters
舍入會給你一個大約2^-53的錯誤,但是這裏的錯誤是一個因子2:'〜0u == UINT_MAX'與'0x80000000 = UINT_MAX/2'。我不認爲這解釋了它。 – MSalters