То, что это работает, совсем не тривиально!Это свойство представления IEEE с плавающей точкой, что int∘floor = ⌊⋅⌋, если величина рассматриваемых чисел достаточно мала, но возможны разные представления, где int (floor (2.3)) может быть 1.
В этом посте объясняется, почему он работает в этом диапазоне .
В двойном выражении вы можете без проблем представлять 32-битные целые числа.В не может быть проблем с округлением.Точнее, двойные числа могут представлять все целых чисел между 2 53 и -2 53 .
Краткое объяснение : Двойное число может хранить до 53 двоичных цифр.Когда вам требуется больше, число дополняется нулями справа.
Из этого следует, что 53 - это наибольшее число, которое можно сохранить без заполнения.Естественно, все (целые) числа, требующие меньше цифр, могут быть сохранены точно.
Добавление одного к 111 (опущено) 111 (53 единицы) дает 100 ... 000, (53 нуля),Как мы знаем, мы можем хранить 53 цифры, что дает крайнее правое заполнение нулями.
Отсюда 2 53 .
Подробнееподробно: Нам нужно рассмотреть, как работает IEEE-754 с плавающей запятой.
1 bit 11 / 8 52 / 23 # bits double/single precision
[ sign | exponent | mantissa ]
Затем вычисляется число следующим образом (исключая особые случаи, которые здесь не имеют значения):
-1 знак × 1.mantissa × 2 показатель степени - смещение
где смещение = 2 экспонента - 1 - 1 , то есть 1023 и 127 для двойной / одинарной точности соответственно.
Зная, что умножение на 2 X просто сдвигаетвсе биты X расположены слева, легко увидеть, что любое целое число должно иметь все биты в мантиссе, которые заканчиваются справа от десятичной точки до нуля.
Любое целое число, кроме нуля, имеетследующая форма в двоичном виде:
1x ... x , где x -e представляют биты справа от MSB (наиболее значимо)бит не может).
Поскольку мы исключили ноль, всегда будет MSB, равным единице, поэтому он не сохраняется.Чтобы сохранить целое число, мы должны привести его в вышеупомянутую форму: -1 знак × 1.mantissa × 2 показатель степени - смещение .
То же самое, что сдвигать биты над десятичной точкой, пока слева от MSB не будет только MSB.Все биты справа от десятичной точки затем сохраняются в мантиссе.
Из этого мы можем видеть, что мы можем хранить не более 52 двоичных цифр, кроме MSB.
Из этого следует, чтонаибольшее число, в котором все биты хранятся в явном виде, составляет
111(omitted)111. that's 53 ones (52 + implicit 1) in the case of doubles.
. Для этого нам нужно установить показатель степени так, чтобы десятичная точка была смещена на 52 позиции.Если бы мы увеличили показатель степени на единицу, мы не могли бы знать цифру справа налево после десятичной точки.
111(omitted)111x.
По соглашению, это 0. Установка нуля всей мантиссы, мы получаем следующеечисло:
100(omitted)00x. = 100(omitted)000.
Это 1, за которым следуют 53 нуля, 52 сохранены и 1 добавлены из-за показателя степени.
Это представляет 2 53 , который отмечает границу (как отрицательную, так и положительную), между которой мы можем точно представить все целые числа.Если бы мы хотели добавить один к 2 53 , нам бы пришлось установить неявный ноль (обозначенный x
) на единицу, но это невозможно.