spamsink: (Default)
[personal profile] spamsink
Как дополнительная точность влияет на результат одной-единственной операции с плавающей точкой.



Режим округления, как это принято по умолчанию — к ближайшему; если ничья, то к четному (tie break to even).

Значение 1/2731 равно (в 16-ричной записи мантиссы, т.е. в представлении формата %a)
0x1.7FF4005FFD0017FF4005FFD001(и т.д. 7FF4005FFD001 в периоде)...p-12
или, в десятичном виде,
3.6616623947272061515928231417...e-4

Результат типа double (53 бита мантиссы), полученный при делении с точностью double (напр. SSE2 на x86_64), будет
0x1.7FF4005FFD001p-12
3.66166239472720588e-4

так как старший бит отбрасываемой части - это старший бит красной 16-ричной цифры 7, т.е. 0.

Результат типа long double (64 бита мантиссы) будет
0x1.7FF4005FFD001800p-12
3.6616623947272061517e-4

(здесь самый младший бит 16-ричного числа 65-й по счету, и с него — с младшего бита красной цифры F, т.е. c 1 — начиналась отбрасываемая части, в которой есть еще биты, равные 1, поэтому округляем вверх).

Соответственно, результат типа double, сохраненный из полученного при делении с точностью long double, из-за округления синих 800 до младшей четной цифры в остающейся части мантиссы, будет
0x1.7FF4005FFD002p-12
3.66166239472720642e-4


Такие дела.

Date: 2014-12-20 01:59 am (UTC)
vak: (Default)
From: [personal profile] vak
Всякое двойное округление есть зло. :)

Date: 2014-12-20 02:36 am (UTC)
From: [identity profile] sab123.livejournal.com
У меня от сравнений десятичных плавающих чисел осталось ощущение, что нужно округлять где-то как минимум два последних десятичных порядка. Что этот пример подтверждает. %15g (или 14? или 16? не помню, судя по этому примеру - 16), что-ли, дает удовлетворительно воспроизводимые результаты. А все, что дальше этой точности - то при переводе в двоичную форму и обратно съезжает в непонять что.

Date: 2014-12-20 03:32 am (UTC)
From: [identity profile] sab123.livejournal.com
О, значит %.14g.
Page generated Mar. 7th, 2026 10:24 pm
Powered by Dreamwidth Studios