Я создаю приложение для вычисления чисел простых чисел в 64-битном диапазоне, поэтому, когда я попытался вычислить квадратный корень из 64-разрядного числа, используя sqrt
функцию от math.h
, я нашел ответ не точным например, когда вход ~0ull
, ответ должен быть ~0u
, но тот, который я получаю, является неправильным, поэтому я решил создать свою версию с использованием языка сборки 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-битный вычислить квадратный корень для него - называть его (а) - затем вычесть нижний 32-бит из 64-битного номера и получить квадратный корень для этого числа - назовите его (b) - теперь все Мне нужно сделать это умножить (а) на (б), и мы закончили. –
@Muhammadalaa: Eh, no. 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