Двойной формат IEEE754 состоит из 1-битного знака, 11-битной экспоненты и 52-битной мантиссы:
7 6 5 4 3 2 1 0
seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
Из-за капризов порядка байтов, этот самый старший байт слевана самом деле ieee(7)
, наименее значимое справа - ieee(0)
- то же самое для mbf()
ниже.
Показатель степени дает значение от 0
до 2047
(2 11 -1) некоторые из которых используются для представления специальных значений, таких как +/-inf
(бесконечность) и nan
(не число).
Биты мантиссы представляют слева направо, 1/2
, 1/4
, 1/8
и так далее.Чтобы получить число, вы вычисляете n = (-1) s x 2 e-bias x 1.m
Двойной двоичный формат Microsoft:1026 *
7 6 5 4 3 2 1 0
eeeeeeee smmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
Код, который вы видите, просто переносит (и слегка изменяет) значения из MBF в формат двойной точности IEEE754.
Чтобы ответить на ваши конкретные вопросы:
Dim sign As Byte = mbf(6) And ToByte(&H80)
В чем причина 'And & H80'?
Hex 80 (&H80
) является двоичным шаблоном 1000 0000
.
Когда вы AND
значение с этим, вы получите &H80
, если этот бит был установлен или 0
в противном случае.
Это просто записывает, каким был знак числа, и вы можете просто перевести его как есть с mbf(6)
на ieee(7)
.
Dim exp As Int16 = mbf(7) - 128S - 1S + 1023S
Почему 1152 (128 + 1 + 1023)?
Показатели в IEEE754 являются смещенными показателями.Другими словами, сохраненные значения могут быть 0
через 255
, но фактические значения, представленные ими, могут быть -128
через 127
(без учета специальных значений на данный момент).
Это позволяет вамиметь отрицательные показатели для очень малых значений и положительные показатели для больших значений.
Показатели MBF также смещены, но они смещены на 128
для одинарного и двойного типов, тогда как показатели двойной точности IEEE754 имеют 0-точка на 1023
.
Причина дополнительного -1
заключается в различиях между MBF и IEEE754 относительно того, куда идет неявный 1
.IEEE754 ставит его перед двоичной точкой, MBF после.Это означает, что показатель степени должен быть скорректирован на единицу.
ieee(7) = ieee(7) Or sign
Почему бы нам просто не сохранить знак в ieee (7)?
Это небольшая загадка, так как ieee(7)
не был явно установлен в этот момент.Я могу только предположить, что ieee()
был инициализирован до нуля при создании, иначе вы можете столкнуться с проблемами, поскольку примерно каждая операция передачи здесь выполняется с OR
.
You.Вы правы, что имеет больше смысла просто использовать ieee(7) = sign
.Фактические значения OR
для объединения битов экспоненты приведены в следующей строке.
ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF)
В чем причина сдвига на 4?
Поскольку показатель IEEE754 пересекает два байта, и вы хотите, чтобы только часть этого показателя в старшем значащем.Семь битов показателя степени входят в старший значащий байт, остальные четыре входят в следующий байт.
Это обрабатывается двумя строками:
ieee(7) = ieee(7) Or ToByte(exp >> 4 And &HFF) ' upper 7 bits '
ieee(6) = ieee(6) Or ToByte(exp << 4 And &HFF) ' lower 4 bits '
С учетом 16-разрядного значения00000abcdefghijk
, рассчитываются два:
>> 4 and &hff : 0abcdefg (s will go at the left)
<< 4 and &hff : hijk0000 (m will go at the right)