Обеспечение двойного C++ - 64 бит

В моей программе на C++ мне нужно извлечь 64-разрядное число с плавающей запятой из внешней последовательности байтов. Есть ли какой-нибудь способ гарантировать, что во время компиляции удваиваются 64-битные? Есть ли какой-то другой тип, который я должен использовать для хранения данных?

Изменить: Если вы читаете это и на самом деле ищете способ обеспечить хранение в формате IEEE 754, взгляните на ответ Адама Розенфилда ниже.

8 ответов

Решение

Улучшение других ответов (в котором предполагается, что символ 8-битный, стандарт не гарантирует этого..). Было бы так:

char a[sizeof(double) * CHAR_BIT == 64];

или же

BOOST_STATIC_ASSERT(sizeof(double) * CHAR_BIT == 64);

Вы можете найти CHAR_BIT, определенный в <limits.h> или же <climits>,

В C99 вы можете просто проверить, если символ препроцессора __STDC_IEC_559__ определено. Если это так, то вам гарантировано, что double будет 8-байтовым значением, представленным в формате IEEE 754 (также известный как IEC 60559). См. Стандарт C99, Приложение F. Однако я не уверен, доступен ли этот символ в C++.

#ifndef __STDC_IEC_559__
#error "Requires IEEE 754 floating point!"
#endif

Кроме того, вы можете проверить предопределенные константы __DBL_DIG__ (должно быть 15), __DBL_MANT_DIG__ (должно быть 53), __DBL_MAX_10_EXP__ (должно быть 308), __DBL_MAX_EXP__ (должно быть 1024), __DBL_MIN_10_EXP (должно быть -307), и __DBL_MIN_EXP__ (должно быть -1021). Они должны быть доступны во всех версиях C и C++.

Проверьте std::numeric_limits< double >::is_iec559 если вам нужно знать, поддерживает ли ваша реализация C++ стандартные двойные числа. Это гарантирует не только то, что общее число битов равно 64, но также размер и положение всех полей внутри двойника.

Я не думаю, что вы должны сосредоточиться на "сыром" размере вашего двойника (который обычно 80-битный, а не 64-битный), а скорее на его точности.

Благодаря numeric_limits::digits10 это довольно просто.

Для этого вы можете использовать статические утверждения Boost. Посмотрите на пример использования в области имен пространства.

Решение без наддува состоит в том, чтобы определить массив так

char a[ 8 == sizeof(double) ];

Если double не 64 бит, то код будет выглядеть

char a[0];

что является ошибкой времени компиляции. Просто поместите соответствующий комментарий рядом с этой инструкцией.

См. Этот пост для аналогичной проблемы и не-ускоренного утверждения времени компиляции под названием CCASSERT.

Для компиляторов, поддерживающих C11 или C++11, я использую что-то похожее на @EvanTeran:

      #include <assert.h> // defines macro static_assert in C11 

static_assert(sizeof(double) * CHAR_BIT == 64, "64-bit double is assumed.");

В С++ 11 или более поздних версиях static_assertявляется ключевым словом.

Другие вопросы по тегам