我创建了一个应用程序来计算64位范围内的质数,所以当我尝试使用math.h
中的sqrt
函数计算64位数字的平方根时,我发现答案不准确。例如,当输入为~0ull
时,答案应该是~0u
,但我得到的却是0x100000000
,这是错误的。因此,我决定使用汇编x86语言创建自己的版本,以查看是否存在bug。以下是我的函数:
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
指令会四舍五入结果?
sqrt(H * 2^32 + L)
=sqrt(L) * sqrt(H*2^32)
,这是不正确的。然而,你可以计算它为sqrt(H) * sqrt(2^32+L/H)
。 - MSalters0x00000000FFFFFFFF
?一开始我读取的结果是从EAX
中获取的,不能是0x100000000
。 - MSalters