"плавающая" и "двойная" точность

Код

float x  = 3.141592653589793238;
double z = 3.141592653589793238;
printf("x=%f\n", x);
printf("z=%f\n", z);
printf("x=%20.18f\n", x);
printf("z=%20.18f\n", z);

предоставит вам выход

x=3.141593
z=3.141593
x=3.141592741012573242
z=3.141592653589793116

где на третьей строке вывода 741012573242 находится мусор, а на четвертой строке 116 - мусор. У удвоений всегда есть 16 значимых цифр, в то время как поплавки всегда имеют 7 значительных цифр? Почему у двух парней 14 значимых цифр?

Ответ 1

Числа с плавающей запятой в C используют кодировку IEEE 754.

Этот тип кодирования использует знак, значение и показатель степени.

Из-за этой кодировки многие номера будут иметь небольшие изменения, чтобы они могли быть сохранены.

Кроме того, число значимых цифр может немного измениться, поскольку оно является двоичным представлением, а не десятичным.

Одиночная точность (float) дает вам 23 бита знака, 8 бит экспоненты и 1 знаковый бит.

Двойная точность (двойная) дает вам 52 бит значимости, 11 бит экспоненты и 1 знаковый бит.

Ответ 2

У удвоения всегда есть 16 значимых цифры, в то время как поплавки всегда имеют 7 значимые фигуры?

Нет. У парных разрядов всегда имеется 53 значащих бита, а у поплавок всегда есть 24 значительных бита (за исключением значений денормальности, бесконечности и NaN, но это темы для другого вопроса). Это двоичные форматы, и вы можете только четко говорить о точности своих представлений в терминах двоичных цифр (бит).

Это аналогично вопросу о том, сколько цифр может быть записано в двоичном целое: 32-битное целое без знака может хранить целые числа до 32 бит, что точно не отображает ни одного числа десятичных цифр: все целые числа можно сохранить до девяти десятичных цифр, но также можно сохранить много 10-значных чисел.

Почему не удваивается имеют 14 значимых цифр?

Кодирование двойника использует 64 бита (1 бит для знака, 11 бит для экспоненты, 52 явных значимых бита и один неявный бит), что вдвое больше числа бит, используемых для представления float (32 бита).

Ответ 3

Обычно он основывается на значительных цифрах как показателя, так и значимости в базе 2, а не на базе 10. Из того, что я могу сказать в стандарте C99, однако, нет определенной точности для float и double (кроме того, что 1 и 1 + 1E-5/1 + 1E-7 различаются [float и double повторно). Тем не менее, количество значимых цифр остается для исполнителя (а также какая база, которую они используют внутри страны, поэтому, другими словами, реализация может решить сделать ее на основе 18 цифр точности в базе 3). [1]

Если вам нужно знать эти значения, константы FLT_RADIX и FLT_MANT_DIGDBL_MANT_DIG/LDBL_MANT_DIG) определены в float.h.

Причина, по которой она называется double, состоит в том, что количество байтов, используемых для ее хранения, удваивает число float (но это включает как показатель, так и значение). Стандарт IEEE 754 (используемый большинством компиляторов) выделяет относительно большее количество бит для значения, чем показатель (от 23 до 9 для float против 52 до 12 для double), поэтому точность более чем удваивается.

1: Раздел 5.2.4.2.2 (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)

Ответ 4

Поплавок имеет 23 бита точности, а double имеет 52.

Ответ 5

float: 23 бита значащего, 8 бит экспоненты и 1 знаковый бит.

double: 52 бит значимости, 11 бит экспоненты и 1 знаковый бит.

Ответ 6

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