Как хранится и вычисляется число с плавающей запятой двойной точности? - PullRequest
2 голосов
/ 04 февраля 2012

Мне очень любопытно, как хранится число с плавающей запятой Double Precision.

Это вещи, которые я до сих пор выяснил.

  1. Им требуется 64 бита в памяти
  2. Состоит из трех частей
    • Бит знака (1длина бита)
    • Экспонент (длина 11 бит)
    • Дробь (53 бита, первый бит всегда принимается равным 1, поэтому сохраняются только 52 бита, кроме случаев, когда все 52 бита равны 0.Тогда предполагается, что начальный бит равен 0)

Однако я не понимаю, что такое экспонента, смещение экспоненты и все эти формулы на странице википедии.

Может ли кто-нибудь объяснить мне, что это за штуки, как они работают и в конечном итоге шаг за шагом переводятся в действительное число?

Ответы [ 3 ]

2 голосов
/ 04 февраля 2012

Ознакомьтесь с формулой чуть дальше вниз по странице:

За исключением вышеприведенных исключений, все число двойной точности описывается следующим образом:

(- 1) ^ знак * 2^ (экспонента - смещение) * 1.mantissa

Формула означает, что для не-NAN, не-INF, ненулевых и неденормальных чисел (которые я буду игнорировать) вы берете биты вмантисса и добавь неявный 1 бит вверху.Это делает мантиссу 53 битами в диапазоне 1,0 ... 1,111111 ... 11 (двоичная).Чтобы получить действительное значение, вы умножаете мантиссу на 2 до степени экспоненты минус смещение (1023) и либо отрицаете результат, либо не зависит от знака.Число 1.0 будет иметь несмещенный показатель степени ноль (т. Е. 1,0 = 1,0 * 2 ^ 0), а его показатель смещения будет 1023 (смещение просто добавляется к показателю степени).Итак, 1.0 будет знак = 1, экспонента = 1023, мантисса = 0 (запомните скрытый бит мантиссы).

Если сложить все это вместе в шестнадцатеричном формате, значение будет 0x3FF000000000 == 1.0.

0 голосов
/ 30 сентября 2015
    int main()
    {
         double num = 5643.0662;
         int sign = 0;
         int exponent = 1035;
         int exponent_bias = 1023;
         float mantissa = 0.0662;

          double x = pow(-1,sign) * pow(2,(exponent - exponent_bias)) * (1+mantissa);
         int y = num - x;

       cout << "\nValue of x is : " << x << endl;
       cout << "\nValue of y is : " << y << endl;

      return 0;
  }
0 голосов
/ 04 февраля 2012
  • Знак: 1, если отрицательный 0, если положительный
  • Фракция: инженерное плавающее представление в двоичном режиме.
  • Exponent: показатель степени e такой, что fraction * 2^e равно числу, которое я хочу представить.
  • Смещение - это число, которое необходимо вычесть показателю степени, чтобы получить правильное представление. В двойной точности 1023, в одинарной 127.

пример (в cause с одинарной точностью мне удобнее писать =)): если бы мне пришлось представлять -0,75, я делаю: - двоичное представление будет -11 * 2^-2 = -1.1 * 2^-1

  • знак = 1
  • дробь = 1 + .1000 ....
  • показатель смещения: -1 + 127 = 126 -> 01111110

так у нас было -0.75 = 1 01111110 10000000000000000000000

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

Для умножения вы должны

  • сумма показателя и вычитание смещения
  • , умноженная на дробную часть
  • округление результата
  • посмотрите на знак (если у вас такой же знак, значит, знак = 0, еще знак = 1)
...