десятичное число и точное представление - PullRequest
1 голос
/ 30 января 2012

В c ++, как узнать, когда десятичное число может быть точно представлено с использованием стандарта IEEE 754-1985.например, 0.2 не может точно представлять.

Есть ли простое правило?

Ответы [ 3 ]

6 голосов
/ 30 января 2012

Число может быть представлено в точности как число с плавающей запятой IEEE755, если оно может быть записано как B & times; 2 n , где B - целое число (а B и n попадают в некоторый допустимый диапазон). Другими словами, должно быть какое-то целое число n , такое, что если вы умножите свое число на 2 n , вы получите целое число. Ясно, что за 1/5 такого нет n .

Еще один способ сказать, что ваше число должно быть суммой конечного числа степеней двух, которые не слишком далеко друг от друга (максимальное расстояние между степенями - это точность вашего числа).

Еще один способ сказать это очень свободно - это то, что «рациональные числа, знаменатель которых является степенью двойки» представимы (хотя и с очевидными ограничениями точности).

Точность числа с плавающей запятой, равная ширине B , составляет 24 бита для одного, 53 бита для двойной и 64 бита для расширенной двойной точности.

5 голосов
/ 30 января 2012

Да, есть простое правило.Если дробная часть не может быть представлена ​​некоторым числом n над некоторой степенью 2, она не может быть точно представлена ​​- она ​​будет повторяться бесконечно.В противном случае оно будет точным до тех пор, пока представление соответствует количеству доступных битов.

Так, например, 0,75 работает, потому что это 3/4.Нет никакого способа заставить 0,2 работать, потому что это 1/5, и вы ничего не можете отрегулировать, чтобы оставить числителю степень 2.

Причина, по которой такое количество десятичных чисел не может быть точно представлено, состоит в томдесятичные числа имеют комбинацию 2 и 5 в знаменателе.Вы можете получить точное представление только в том случае, если вы можете упростить дробь, чтобы удалить все 5.

Чтобы привести другой пример, рассмотрим 0,625.Как часть это 625/1000, но это упрощает до 5/8.Упрощенная форма имеет степень 2 снизу, поэтому она будет точной.

Один интересный побочный эффект заключается в том, что все точно представимые десятичные дроби оканчиваются на «5».Если этого не произойдет, вы можете очень быстро сказать, что это не может быть точно.

1 голос
/ 30 января 2012

Есть ли простое правило?

Эмпирический: преобразовать и преобразовать обратно, и если вы получите одно и то же число, то оно точно представимо.

Теоретическое: IEEE-754 использует знаковый бит, M битов мантиссы и E битов экспоненты (M = 52, E = 11 для 64-бит double, M = 23, E = 8 для 32-бит float), представленный как (+/- 1) * (1 + (m / 2 ^ M)) * (2 ^ (e- (2 ^ (E-1) -1))),для m = беззнаковая M-битная мантисса, e = беззнаковая E-битная экспонента.Если ваш номер может быть представлен таким образом, то он точно представлен.(Существуют также субнормальные числа для еще меньших показателей, которые вписываются в битовое пространство чисел с плавающей запятой)

В переводе на английский язык вышеизложенное означает, что если ваше число X можно записать как0 или (+/- 1) * неотрицательное нечетное целое число m ', умноженное на степень 2 2 (e'), тогда X может быть представимым;чтобы убедиться, что вы должны проверить, соответствуют ли m 'и e' их соответствующим битам:

m '= 2k + 1, k <2 ^ M </p>

e' = диапазон экспонентычто я недостаточно уверен в своей алгебре, чтобы убедиться, что я прав.В любом месте в пределах +/- 900 для чисел с двойной точностью все в порядке, но если показатель больше 900 по величине, то вам нужно быть осторожным и действительно следует более внимательно изучить способ представления битов.

...