Как отличить 1 от нуля и значения с плавающей точкой? - PullRequest
0 голосов
/ 28 января 2011

Я знаю, что это может быть нубский вопрос, но, поскольку он не включен в электронную книгу, которую я изучаю, я задам его.В стандартном двоичном формате IEEE с плавающей запятой, фактически представляющем числа в научной нотации, я знаю, что целочисленное значение, равное единице, всегда предполагается добавленным к дробной части, иллюстрируемой значимым и частью двоичного кода, и не включается в двоичный кодменя смущает то, как отличить 1 от нуля и значения с плавающей запятой, потому что я предполагаю, что оба имеют абсолютно нулевое значение, и я предполагаю, что дифференцирование здесь должно быть выполнено экспоненциальной частью, но не знаю как!

Ответы [ 2 ]

6 голосов
/ 28 января 2011

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

Статья Википедии о IEEEСтандарт 754 содержит список точных битовых комбинаций.

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

Я написал ответ, упоминая (среди прочего) неявный бит (что, я полагаю, вам интересно) здесь https://stackoverflow.com/questions/327020/why-are-floating-point-values-so-prolific/4164252#4164252

Я подробно остановлюсь здесь. Я буду использовать последовательности символов «<=>» и «=>» для обозначения «эквивалентно» и «давать».

Если вы посмотрите на число iEEE-754 с плавающей запятой одинарной точности (SPFP) в 32-битном формате без знака, вот как можно извлечь отдельные части:

  • Знак: И с 0x80000000 (1 бит) и смещением вправо на 31 позицию
  • Экспонент: И с 0x7f800000 (8 биты) и сдвиг вправо на 23 места
  • Значение (мантисса): И с 0x007fffff (23 бита). Если оригинал число с плавающей точкой ненулевое вы ИЛИ в «неявном» бите с 0x00800000 (=> 24 бита в значении).

Существует два варианта нуля: 0,0 и -0,0 (0x00000000 и 0x80000000). Экспонента = 0 и значимое = 0 определяют ноль. Таким же образом есть также два варианта одного: 1,0 и -1,0 (0x3f800000 и 0xbf800000). Как видите, здесь нет путаницы 0.0 и 1.0. Я постараюсь объяснить, почему.

Любое ненулевое число будет иметь показатель степени в диапазоне от 0x01 до 0xfe. Несколько упрощенный показатель 0x00 с ненулевым значением используется для случая результата с недостаточным значением, а показатель 0xff с ненулевым значением для случая результата с переполнением (т.е. исключения SPFP). Показатель степени, соответствующий 1,0, равен 0x7f, что соответствует 0 (см. Следующий абзац), что дает 2 ^ 0 = 1. Следующий показатель чуть ниже равен 0x7e и соответствует -1, что дает 2 ^ -1 = 0,5 и так далее. Для показателя степени 0x7f при значенииand будет пытаться представить все числа в диапазоне 1,0 <= x <2,0, то есть показатель степени определяет нижний предел чисел, которые вы хотите представить, который может доходить до, но не включая следующий более высокий. 2 показатель степени. </p>

Если вам трудно понять показатель, и вы хотите, чтобы он выглядел «более нормальным» (будучи базовым 10 человек), вы можете вычесть из него 0x7f (127) и получите диапазон от -126 до 127. -128 будет показателем переполнения, а -127 - недостатком.

Точно так же вы не думаете, что я забыл: если у вас установлен знаковый бит, экспонента 0x7f попытается представить все числа в диапазоне -1.0> = x> -2.0.

Теперь к неявному биту. Неявный бит можно назвать битом «22,5», поскольку он находится между самым старшим явным битом значимости и самым младшим явным битом экспоненты. Его значение - 1 для экспоненты. Таким образом, для показателя степени 0x7f (<=> 0 => 2 ^ 0) это означает, что 1.0 является компонентом представляемого действительного числа. Первый явный бит справа от него (бит 22 мантиссы) сигнализирует, если число, соответствующее следующему меньшему показателю (07f-0x01 = 0x7e <=> -1 => 2 ^ -1) или 0,5, является компонентом реальное число и тд. Поэтому наименьший компонент значения с плавающей запятой одинарной точности с показателем 0x7f составляет 0x7f - 23 (биты в значении) = 0x68 (<=> -23 => 2 ^ -23). ​​

Чтобы сложить все вместе: действительное число, соответствующее значению SPFP 0x42b80000, является показателем 0x85-0x7f = 6 => 64.0 для неявного бита:

  • 2 ^ 6 * 1 (неявный бит всегда 1) +
  • 2 ^ 5 * 0 (бит 22 значения и сброс) +
  • 2 ^ 4 * 1 (бит 21 установлен) +
  • 2 ^ 3 * 1 (установлен бит 20) +
  • 2 ^ 2 * 1 (бит 19 установлен) +
  • (биты с 18 по 0 сбрасываются и их соответствующие компоненты (от 2 ^ 1 до 2 ^ -17) поэтому не используются)

2 ^ 6 + 2 ^ 4 + 2 ^ 3 + 2 ^ 2 => 64 + 16 + 8 + 4 => 92,0, что является действительным числом, представленным 0x42b80000.

В этом примере вы можете видеть, как / что значение и регулируется влево, что позволяет неявному биту 22,5 формата SPFP стать явным битом 23 (хотя всегда установлен) значения и, таким образом, добавляя дополнительный бит точности к формат SPFP. Формат DPFP (Double Precision) аналогичен, но диапазон экспонент больше, а значение - больше.

Я рекомендую вам поэкспериментировать с форматом. Мое личное предположение состоит в том, что 99% всех программистов никогда не имеют.

...