Официальный способ узнать, как кодируются данные с плавающей запятой, - это прочитать документацию о реализации C ++, потому что стандарт C ++ 2017 года гласит в 6.9.1 «Основные типы» [basic.fundamental], параграф 8, черновикN4659:
… Представление значений типов с плавающей запятой определяется реализацией…
«Определено реализацией» означает, что реализация должна документировать его (3.12 «Реализация -определенное поведение »[defns.impl.defined]).
Стандарт C ++ представляется в этом отношении неполным, так как он говорит:« ... представление значения - это набор битов в представлении объекта, определяющий значение … »(6,9« Типы »[basic.types] 4) и« представление объекта объекта типа T
представляет собой последовательность N unsigned char
объекты, занятые объектом типа T
,… ”( ibid ), но я не вижу, чтобы в нем говорилось, что реализация должна определять, какой из битов впредставление объекта - это представление значения или в каком порядке / отображении. Тем не менее, ответственность за информирование вас о характеристиках реализации C ++ лежит на реализации и разработчиках, потому что ни одна другая сторона не может это сделать. (То есть, разработчики создают реализацию, и они могут делать это произвольным образом, поэтому именно они определяют характеристики и являются источником этой информации.)
Стандарт Cопределяет некоторые математические характеристики типов с плавающей точкой и требует реализации, чтобы описать их в <float.h>
. C ++ наследует их в <cfloat>
(C ++ 20.5.1.2 «Заголовок» [заголовки] 3-4). C 2011 5.2.4.2.2 «Характеристики плавающих типов <float.h>
» определяет модель, в которой число с плавающей точкой x равно sb e сумма ( f k b - k для k = от 1 до p ), где s - знак (± 1), b - основание или основание, e - это показатель степени между e min и e max включительно, p - точность (число базовых - b цифр в значимом) и f k - базовых - b цифрзначимое (неотрицательные целые числа меньше b ). Тип с плавающей запятой может также содержать бесконечность и не-число (NaN) «значения», а некоторые значения различаются как нормальные или субнормальные. Затем <float.h>
связывает параметры этой модели:
FLT_RADIX
предоставляет базу, b . FLT_MANT_DIG
, DBL_MANT_DIG
иLDBL_MANT_DIG
- количество цифр и цифр, также известных как точность, p для типов float
, double
и long double
соответственно. FLT_MIN_EXP
, DBL_MIN_EXP
, LDBL_MIN_EXP
, FLT_MAX_EXP
, DBL_MAX_EXP
и LDBL_MAX_EXP
обеспечивают минимальные и максимальные показатели, e min и e max .
В дополнение к предоставлению их в <cfloat>
, C ++ предоставляет их в шаблоне numeric_limits
, определенном в заголовке <numerics>
(21.3.4.1 «numeric_limits»члены »[numeric.limits.members]) в radix
( b ), digits
( p ), min_exponent
( e min ) и max_exponent
( e max ). Например, std::numeric_limits<double>::digits
дает количество цифр в значении и типа double
. Этот шаблон включает в себя другие члены, которые описывают тип с плавающей точкой, например, поддерживает ли он бесконечности, NaN и субнормальные значения.
Они предоставляют полное описание математических свойств формата с плавающей точкой. Однако, как указано выше, C ++, по-видимому, не в состоянии указать, что реализация должна документировать, как биты значений, которые представляют тип, появляются в битах объекта.
Многие реализации C ++ используют базовый IEEE-75432-битный двоичный формат для float
и 64-битный формат для double
, а биты значений отображаются в биты объекта так же, как и для целых чисел соответствующей ширины. Если это так, для нормальных чисел знак s кодируется в старшем значащем бите (0 или 1 для +1 или -1, соответственно), показатель степени e кодируется с использованиемсмещенное значение e + 126 (float
) или e + 1022 (double
) в следующих 8 (float
) или 11 (double
) битах, иостальные биты содержат цифры f k для k от 2 до p . Первая цифра, f 1 , равна 1 для нормальных чисел. Для субнормальных чисел поле экспоненты равно нулю, а f 1 равно 0. (Обратите внимание, что здесь смещения составляют 126 и 1022 вместо 127 и 1023, используемых в IEEE-754, посколькуМодель C выражает значение и используя b - k вместо b 1− k как используется в IEEE-754.) Бесконечности кодируются всеми единицами в поле экспоненты и всеми нулями в значимом поле. NaN кодируются всеми единицами в поле экспоненты, а не всеми нулями в значимом поле.