Каков размер float и double в C и С++?

Я смотрел, есть ли какой-либо стандартный тип, похожий на uint32_t, который всегда будет отображаться в 32-битный неподписанный тип интеграла, но я не смог найти его.

Является ли размер float всегда 4 байта на всей платформе?
Является ли размер double всегда 8?

Есть ли какой-либо стандарт, говорящий по этому поводу?

Я хочу убедиться, что мой размер всегда один и тот же на всех платформах (x86 и x64), поэтому я использую стандартные типы int, но я не смог найти аналогичный typedef для float и double.

Ответ 1

Выдержка из стандарта C99, нормативное приложение F (стандарт С++ не содержит явного упоминания об этом приложении, хотя он включает все затронутые функции без изменений для каждой ссылки. Кроме того, типы должны соответствовать совместимости.):

IEC 60559 с плавающей точкой арифметики

F.1 Введение

1 В этом приложении указывается поддержка языка C стандарта IEC 60559 с плавающей запятой. Стандартом с плавающей точкой стандарта IEC 60559 является, в частности, двоичная арифметика с плавающей запятой для микропроцессорные системы, второе издание (IEC 60559: 1989), ранее обозначенное IEC 559: 1989 и в качестве стандарта IEEE для двоичной арифметики с плавающей запятой (ANSI/IEEE 754-1985). Стандарт IEEE для независимой от Radix плавающей точки Арифметика (ANSI/IEEE 854-1987) обобщает двоичный стандарт для удаления зависимостей от радиуса и длины слова. IEC 60559 обычно относится к плавающей точке как в стандарте IEC 60559, в стандарте IEC 60559 и т.д. Реализация, которая определяет __STDC_IEC_559__, должен соответствовать спецификациям в этом приложении .356) Если указана привязка между языком C и IEC 60559, Поведение, указанное в соответствии с IEC 60559, принимается по ссылке, если не указано иное. поскольку отрицательная и положительная бесконечность представлены в форматах МЭК 60559, все действительные числа лежат в пределах диапазона отображаемых значений.

Итак, включите <math.h> (или в С++, возможно, <cmath>), и проверьте __STDC_IEC_559__.

Если макрос определен, уточняются не только типы (float - 32 бит, а double - 64 бита), но и поведение встроенных операторов и стандартных функций. Отсутствие макроса не дает никаких гарантий.

Для x86 и x86_64 (amd64) вы можете полагаться на типы float и double, совместимые с IEC-60559, хотя функции, использующие их, и операции с ними могут быть не такими.

Ответ 2

Не говорит ничего о размере.

3.9.1.8

Существует три типа с плавающей запятой: float, double и long double. Тип double обеспечивает как минимум такую ​​же точность, как float, и тип long double обеспечивает как минимум такую ​​же точность, как double. множество значений типа float является подмножеством множества значений тип double; набор значений типа double является подмножеством набор значений типа long double. Представление значения типы с плавающей запятой определяются реализацией. Интегральные и плавающие типы коллективно называются арифметическими типами. Специализации стандартный шаблон std:: numeric_limits (18.3) должен указывать максимальный и минимальные значения для каждого арифметического типа для реализации.

Ответ 3

Стандарт С++ ничего не говорит, но на большинстве платформ С++ используют стандарт single/double precision от IEEE, который определяет единую точность как 4 байта, а двойную точность - 8 байтов.

http://en.wikipedia.org/wiki/Single-precision_floating-point_format http://en.wikipedia.org/wiki/Double-precision_floating-point_format

Я не уверен в исключениях для этих случаев.

Ответ 4

Поскольку операции с плавающей запятой реализованы на низком уровне процессорами, стандарт С++ не задает размер для a float, double или long double. Все, что он говорит, это то, что порядок, который я им задал, находится в равном или увеличивающемся порядке точности.

Лучше всего использовать static_assert, sizeof, typedef и #define осторожно, чтобы определить типы с плавающей запятой кросс-платформы.

Ответ 5

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

"Интегрированные типы С++, унаследованные от C, представляют собой кросс-платформенную опасность. int, long и друзья имеют разные размеры на разных платформах (32-разрядные и 64-разрядные на сегодняшних системах, возможно, на 128 бит позже). приложений, это может показаться нерелевантным, поскольку они никогда не подходят к 32-битовому пределу (а точнее 31-битовому, если вы используете целые числа без знака), но если вы сериализуете свои объекты в 64-разрядной системе и десериализуете 32-битную систему, неприятно удивил. APR предоставляет набор typedef для базовых типов, которые могут отличаться на разных платформах. Эти typedefs обеспечивают гарантированный размер и избегают нечетких встроенных типов. Однако для некоторых приложений (в основном числовых) иногда важно использовать собственный размер машинного слова (как правило, что означает int) для достижения максимальной производительности ".

Gigi SAYFAN - Создание собственной плагиновой платформы http://philippe.ameline.free.fr/techytechy/071125_PluginFramework.htm)

Ответ 6

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

Ответ 7

В случае X86, даже если с использованием номеров одиночной и двойной точности IEEE, на внутренние вычисления влияет слово управления с плавающей запятой (FCW). Внутренние вычисления обычно 64 бит или 80 бит (длинный двойной). Вы можете переопределить это с помощью встроенного ассемблерного кода, но нет гарантии, что некоторая функция библиотеки с двойной точностью не вернет его.

Microsoft поддерживала 80-битные удваивания с 16-битными компиляторами, но отказалась от поддержки с их 32-битными и 64-битными компиляторами, а длинные удвоения теперь совпадают с удвоениями в 64 бит.