В этом примере легко увидеть, что происходит, просмотрев числа в шестнадцатеричном формате с плавающей запятой. Результатом преобразования исходного текста 3.472727272727276
в double
будет 3,47272727272727621539161191321909427642822265625, что в шестнадцатеричном формате:
1.BC8253C8253D0<sub>16</sub>•2<sup>1</sup>
Обратите внимание, что в мантиссе ровно 53 бита - один перед "." и 52 в 13 шестнадцатеричных цифрах после него. Формат double
имеет один бит для знака, 11 для экспоненты и 53 для мантиссы. (52 хранятся явно; один кодируется через показатель степени.)
Преобразование исходного текста 3.4727272727272767
в double
дает 3,472727272727276659480821763281710445880889892578125, что составляет:
1.BC8253C8253D1<sub>16</sub>•2<sup>1</sup>
Теперь мы можем легко посмотрим, что получится с арифметией c на них. Их разница:
0.0000000000001<sub>16</sub>•2<sup>1</sup>
Когда мы нормализуем это, это 1. 16 • 2 1-52 = 1. 16 • 2 -51 ≈ 4,44 • 10 -16 , а формат double
может легко представить половину этого, просто изменяя показатель степени. Тогда у нас есть 1. 16 • 2 −52 ≈ 2,22 • 10 −16 .
Однако, когда мы пытаемся сложить половину отличие от первого числа, результат с арифметикой действительных чисел c будет:
1.BC8253C8253D08<sub>16</sub>•2<sup>1</sup>
Обратите внимание, что это 54 бита - один перед «.», затем 52 в 13 шестнадцатеричных цифрах и последний один в старшем бите этого 14 th di git, 8. Формат double
не имеет 54 бит в своем значении, поэтому сложение в формате double
не может дать такого результата. Вместо этого сумма округляется до ближайшего представимого значения или, в случае ie, до ближайшего представимого значения с четным младшим битом. Таким образом, результат будет 1.BC8253C8253D08 16 • 2 1 , что совпадает с min
.