Как узнать, как мой компилятор кодирует данные с плавающей точкой? - PullRequest
0 голосов
/ 31 октября 2019

Как узнать, как данные с плавающей запятой хранятся в программе на C ++?
Если я назначу число 1.23, например, двойному объекту, как я узнаю, как это число закодировано?

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Официальный способ узнать, как кодируются данные с плавающей запятой, - это прочитать документацию о реализации 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 кодируются всеми единицами в поле экспоненты, а не всеми нулями в значимом поле.

1 голос
/ 31 октября 2019

Компилятор будет использовать кодировку, используемую архитектурой ЦП, для которой вы компилируете. (Если только эта архитектура не поддерживает плавающую точку, в этом случае компилятор, вероятно, выберет кодировку, которую они будут использовать для эмуляции).

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

Стандарт IEEE 754 довольно распространен.

...