Преобразование десятичного числа в экспоненциальном представлении в IEEE 754

Я прочитал несколько текстов и потоков, показывающих, как преобразовать десятичное число в IEEE 754, но я все еще не понимаю, как я могу преобразовать число без расширения десятичного числа (которое представлено в научной нотации)

Число, с которым я особенно работаю, это 9.07 * 10^23, но подойдет любое число; Я выясню, как это сделать для моего конкретного примера.


person Xecure    schedule 15.09.2011    source источник


Ответы (2)


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

Для большинства чисел есть способ сделать это относительно быстро. Вот как это работает в двух словах.

Вам нужно разделить число либо на произведение, либо на дробь чисел, которые имеют точное представление в виде числа с плавающей запятой. Наибольшая степень числа 10, которую можно точно представить, равна 10^22. Итак, чтобы получить 9.07e+23 в виде с плавающей запятой, мы можем написать:

9.07e+23 = 907 * 10^21

Согласно стандарту IEEE-754, одна операция с плавающей запятой гарантированно будет правильно округлена, поэтому указанный выше продукт, вычисленный как произведение двух чисел с плавающей запятой двойной точности, даст правильно округленный результат.

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

Обратите внимание, что вы не можете использовать этот метод для 9.07e-23. Это число равно 907/10^23, поэтому знаменатель будет слишком большим, чтобы его можно было точно представить. В этой ситуации, а также в других случаях, связанных с очень большими или очень маленькими числами, вы должны использовать какую-либо форму высокоточной арифметики.

См. быстрое преобразование десятичных чисел в числа с плавающей запятой. дополнительные подробности и примеры.

person Jeffrey Sax    schedule 17.09.2011

Преобразование числа из десятичной строки в двоичную IEEE довольно просто, если вы знаете, как выполнять сложение и умножение IEEE с плавающей запятой. (или если вы используете любой базовый язык программирования, такой как C/C++)

Есть много разных подходов к этому, но проще всего оценить 9.07 * 10^23 напрямую.

Во-первых, начните с 9.07:

9.07 = 9 + 0 * 10^-1 + 7 * 10^-2

Теперь оцените 10^23. Это можно сделать, начав с 10 и используя любой алгоритм усиления.

Затем умножьте полученные результаты.

Вот простая реализация на C/C++:

double mantissa = 9;
mantissa += 0 / 10.;
mantissa += 7 / 100.;

double exp = 1;
for (int i = 0; i < 23; i++){
    exp *= 10;
}

double result = mantissa * exp;

Теперь вернуться назад (IEEE -> к десятичному) намного сложнее.

Опять же, есть много разных подходов. Вот самый простой, который я могу придумать.

Я буду использовать 1.0011101b * 2^40 в качестве примера. (мантисса в двоичном формате)

Во-первых, преобразуйте мантиссу в десятичную: (это должно быть легко, так как нет экспоненты)

1.0011101b * 2^40 = 1.22656 * 2^40

Теперь «масштабируйте» число так, чтобы двоичная экспонента исчезла. Это делается путем умножения на соответствующую степень 10, чтобы «избавиться» от двоичного показателя степени.

1.22656 * 2^40 = 1.22656 * (2^40 * 10^-12) * 10^12
               = 1.22656 * (1.09951) * 10^12
               = 1.34861 * 10^12

Итак, ответ:

1.0011101b * 2^40 = 1.34861 * 10^12

В этом примере 10^12 было необходимо, чтобы «уменьшить масштаб» 2^40. Определение степени 10, которая необходима, просто равно:

power of 10 = (power of 2) * log(2)/log(10)
person Mysticial    schedule 15.09.2011
comment
Ваш метод не всегда дает правильно округленные результаты. Попробуйте это для 9.09e23, и вы обнаружите, что 9.09e23 - (9 + 9/100.0) * 1e23 не равно нулю. - person Jeffrey Sax; 18.09.2011
comment
ОП никогда не говорил, что он должен быть правильно округлен. Вам почти наверняка понадобится арифметика с высокой точностью, чтобы правильно округлить ее - и это еще одна тема... - person Mysticial; 18.09.2011