Разрывы между последовательными числами с плавающей запятой

(все обсуждаемые числа в десятичном виде)

Допустим, у нас есть тип данных с плавающей запятой, который похож на:

м * 10 ^ е

where m is the mantissa . and max mantissa size is 1 ( 0 <= m <= 9);

e is the exponent and its size is  -1 <= e <= 1

мы говорим, что максимальное значение типа данных равно 90, а минимальное значение равно 0.

НО: это не означает, что мы можем представить все числа, которые находятся в этом пределе. мы можем представить только 27 чисел ( 9 * 3), исключая ноль.

в частности, мы не можем представить 89 таким образом, так как он имеет двухзначную мантиссу (и ни одна из них не равна нулю).

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

является аргументом выше. если это, пожалуйста, приведите пример, как показать это в Java или C?

2 ответа

Решение

Ваши рассуждения совершенно обоснованы. Проще всего показать это, например, как вы.

Непредставимый пример

Рассмотрим формат "обычный с плавающей запятой", как определено IEEE-754, он имеет 7 битов экспоненты, таким образом, диапазон за пределами [-2^127,2^127],

Он также имеет 24 бита мантиссы, поэтому давайте рассмотрим 67108864, 67108865 и 67108866. Эти числа соответственно 2^26, 2^26+1 и 2^26+2.

Попробуйте их нормализовать, чтобы записать их в формате с плавающей запятой, и вы увидите, что

  • мантисса приобретает значение 26
  • первый бит исчезает, поскольку в формате IEEE-754 подразумевается, что первое число всегда равно * 1, поэтому у вас остается 25 бит на каждое число
  • все последующие биты (в пределах 24 бит) составляют мантиссу...
    • 67108864 имеет только нули в мантиссе, так как его наименьший бит равен 0, вы можете удалить его без потери информации.
    • 67108866 имеет 1 в последней позиции своей мантиссы, так как его наименьший бит также равен 0, вы все равно можете удалить его без потери информации.
    • 67108865 имеет только нули и наименьший бит 1, что превышает 24 бита! Таким образом, число будет округлено до 2 ^ 26 или 2^26+2.

Таким образом, у вас есть пример, например, 89: 67108865, не представимый в float.


* за исключением субнормалей, см. ниже (расширение комментария)

предвзятость

На самом деле я пропустил часть здесь. Показатель степени не кодируется напрямую в зарезервированных для него битах, он смещен. В случае одиночных чисел с плавающей точкой, смещение составляет 127.

Таким образом, наши 26 на самом деле представлены 26+127, то есть 153. Кража следующего изображения из Википедии:

отрицательный нулевой рисунок для иллюстрации формата с плавающей запятой

Если вы возьмете эти числа (знак, экспонента и мантисса) в том виде, как они написаны, и хотите выразить не субнормальное число, вы получите: (-1)знак * 2(экспонента-127) * 1.mantissa

Subnormals

Как только мы достигаем наименьшего возможного показателя степени, то есть, когда мы записываем его 0 и означаем -127, мы прекращаем предполагать начальные 1. Таким образом, мы можем представлять числа, меньшие 2-127 (жертвуя точностью, потому что у нас будет ведущая 0 на мантиссе).

Затем мы имеем: (-1)знак * 2-127 * 0.mantissa

В частности, когда у мантиссы все 0, у нас есть 0, и это предназначено: теперь число, имеющее только 0 в двоичном представлении, читается как 0. В некотором смысле, 0 является наименьшим из ненормальных чисел (хотя на практике люди считают это просто частным случаем самостоятельно).

Другие особые случаи - когда показатель степени равен единице. Если у мантиссы все 0, то у вас +/- бесконечность (в зависимости от знака), а если установлены некоторые биты мантиссы, у вас есть NaN.

Да, ваши рассуждения верны, и должно быть легко найти реальные числа, которые не могут быть представлены в вашем типе данных.

Рассмотрим наименьшую мантиссу (0) и показатель степени (-1), которую вы допускаете:

0 * 10 ^ -1

= 0.0

Следующая более высокая мантисса, которую вы разрешаете, - 1:

1 * 10 ^ -1

= 0,1

Вы не можете представлять какие-либо действительные числа в диапазоне от 0,0 до 0,1, например 0,05.

Вы должны быть в состоянии выразить это в Java или C.

Другие вопросы по тегам