большое целое число с плавающей запятой

Я пытаюсь преобразовать большое целое число в 32-битное число с плавающей запятой одинарной точности, но я не могу решить эту проблему, с которой столкнулся. Что, если двоичное представление большого целого числа больше, чем 23-битная мантисса.

Например, возьмем целое число 1 671 277 287.

Его двоичное представление: 01100011100111011010101011100111.

Насколько я понимаю, вы перемещаете десятичный разряд влево до тех пор, пока слева от него не останется только 1 бит, например:

01.100011100111011010101011100111

Моя проблема в том, что эта мантисса составляет 30 бит, а одинарная точность с плавающей запятой имеет место только для 23 бит мантиссы. Я пытался искать эту конкретную проблему, но ничего не нашел. Как бы я справился с этим?

РЕДАКТИРОВАТЬ: Узнал некоторую информацию на случай, если у кого-то еще возникнет эта проблема. Округление по умолчанию для одинарной точности с плавающей запятой — «округление до ближайшего, привязка к четному». В другом сообщении StackOverflow рассказывается, как это легко сделать.

сообщение StackOverflow об округлении


person Alex Anderson    schedule 02.09.2015    source источник
comment
Вы ничего не упускаете - 32-битное число с плавающей запятой одинарной точности имеет меньше значащих цифр точности (6-7 десятичных цифр), чем 32-битное целое число, из-за того, что оно имеет только 23-битную мантисса. Таким образом, эти наименее значимые биты в вашем примере выпадут из конца.   -  person Paul R    schedule 03.09.2015
comment
Обратите внимание, что, предполагая IEEE754, у вас есть 24 бита благодаря подразумеваемой ведущей 1. Но это все еще не дает 30 бит, поэтому способ сделать это - соответствующим образом округлить - то есть w.r.t. Действует режим округления IEEE754, по умолчанию округление до ближайшего, привязка к четному.   -  person aka.nice    schedule 03.09.2015
comment
@PaulR Итак, 30-битная мантисса 100011100111011010101011100111 — это всего лишь 10001110011101101010101 с крайними правыми 7 битами?   -  person Alex Anderson    schedule 03.09.2015
comment
@AlexAnderson: да, в значительной степени, хотя обычно вы применяете округление, а не просто усекаете мантиссу, как отмечено в комментарии выше.   -  person Paul R    schedule 03.09.2015


Ответы (1)


Этот вопрос сводится к тому, как округлить 1000_1110_0111_0110_1010_1011_1001_11 до 23 бит. Я собираюсь принять обычный режим округления по умолчанию, который округляется до ближайшего с округлением до четного в качестве прерывания связи.

Старшие 23 бита: 1000_1110_0111_0110_1010_101. Самый значащий отброшенный бит равен 1, и есть ненулевые биты с более низким значением.

Общее правило таково:

  • Если первый отброшенный бит равен 0, округлить в меньшую сторону.
  • Если первый отброшенный бит равен 1, а младшие биты равны нулю, округлить до четного.
  • Если первый отброшенный бит равен единице и есть ненулевые биты с более низким значением, округлить в большую сторону.

Здесь действует третье из этих правил, поэтому округляйте до 1000_1110_0111_0110_1010_110.

person Patricia Shanahan    schedule 03.09.2015