Преобразование Double в Float и наоборот вручную - PullRequest
1 голос
/ 28 февраля 2020

Я знаю, что double - это 64 бита, а float - 32 бита:

Float:

1 bit for the sign
8 bits for the exponent
24 bits for the fraction

Double:

1 bit for the sign
11 bits for the exponent
53 bits for the fraction / mantissa

Вопрос в том, как мы конвертируем их друг другу вручную? (Я знаю, точность будет потеряна). Это просто 32 bit right shift для преобразования double в float? И 32 bit left shift, чтобы преобразовать число с плавающей запятой в удвоенный?

1 Ответ

3 голосов
/ 28 февраля 2020

Отложить в сторону знак; оно одинаково для обоих форматов.

Если в поле экспоненты все единицы:

  • Элемент представляет собой бесконечность или NaN.
  • Если поле значим и все нули, данные - это бесконечность. Вернуть число в формате назначения со знаком сверху, полем экспоненты всех единиц и значимым полем всех нулей.
  • В противном случае, датумом является NaN. Возвращает число в формате назначения со знаком сверху, полем экспоненты всех единиц и значением и измененным некоторым разумным способом (это не полностью определено стандартами).

Если Поле экспоненты не является ни единицами, ни всеми нулями:

  • Возьмите поле экспоненты как двоичное число (например, 110111 равно 103). Вычтите смещение для этого формата (127 для двоичного кода IEEE-754, 1023 для двоичного кода 64). Это дает вам фактический показатель степени.
  • Формирует двоичное число из «1». за ним следуют биты поля значимости, например «1.00001111000000000000001». Это дает вам реальное значение. Продолжите ниже.

Если в поле экспоненты все нули:

  • Начните с 1 и вычтите смещение для формата. Это дает вам фактический показатель степени.
  • Формирует двоичное число от «0». за ним следуют биты поля значимостей, например «0.00001111000000000000001». Это дает вам реальное значение. Продолжите ниже.

Если фактическое значение и равно нулю, верните число в формате назначения, образованное знаком сверху, все нули в поле экспоненты и все нули в поле значим.

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

Если фактический показатель степени равен или превышает максимальный конечный показатель степени для формата назначения (127 для двоичного кода32, 1023 для двоичного кода 64):

  • Если он превышает максимальный конечный показатель степени, вернуть бесконечность, как описано выше.
  • Если он просто равен максимальному конечному показателю степени, округлите значениеifyand до числа значащих бит в формате назначения (24 для двоичного кода32, 53 для двоичного кода64) (используя любое действующее правило округления, часто округляя до ближайших связей к четным). Если это вызывает округление до (двоичного) значения «10», верните бесконечность, как указано выше. В противном случае продолжите ниже.

Если фактическая экспонента равна или превышает минимальную нормальную экспоненту для формата назначения (-126 для двоичного32, -1022 для двоичного 64):

  • Округлить значение и количество значащих и битов в целевом формате.
  • Удалите начальный «1». от значения и использовать биты после «.» (23 бита для двоичного 32, 52 для двоичного 64), чтобы сформировать кодирование значений и.
  • Добавьте смещение для формата к показателю степени, чтобы сформировать смещенный показатель.
  • Вернуть число в формате назначения со знаком сверху, смещенным показателем степени и значением и кодировкой.

В противном случае результат является ненормальным (и может округляться до нуля):

  • Пусть S будет минимальный нормальный показатель минус фактический показатель.
  • Позвольте P быть количеством битов в значе и поле в формате пункта назначения (23 для двоичного32, 52 для двоичного 64) минус S. (P + 1 является числом биты, доступные в формате назначения для значимого, с учетом субнормального показателя степени. Может быть нулевым или отрицательным, но приведенное ниже округление может эффективно довести его до 1.)
  • Умножить значимое и на 2 P и округлите его до целого числа (используя любое действующее правило округления).
  • Возвращает число в формате назначения со знаком сверху, expone Не поле всех нулей, а поле значимости и округленное значение сверху и сверху (взятое как целое число, представленное в двоичном виде). ​​
...