Обеспечение двойного C ++ - 64 бит - PullRequest
18 голосов
/ 15 апреля 2009

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

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

Ответы [ 7 ]

27 голосов
/ 15 апреля 2009

В C99 вы можете просто проверить, определен ли символ препроцессора __STDC_IEC_559__. Если это так, то вам гарантировано, что double будет 8-байтовым значением, представленным в формате IEEE 754 (также известный как МЭК 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 ++.

11 голосов
/ 15 апреля 2009

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

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

или

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

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

7 голосов
/ 17 апреля 2009

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

6 голосов
/ 15 апреля 2009

Не думаю, что вам следует фокусироваться на «сыром» размере вашего двойника (который обычно составляет 80 бит, а не 64 бит), а скорее на его точности.

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

5 голосов
/ 15 апреля 2009

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

4 голосов
/ 15 апреля 2009

Решение без форсирования - определить массив следующим образом:

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

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

char a[0];

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

1 голос
/ 15 апреля 2009

См. в этом посте , где описана похожая проблема и утверждение без компиляции, называемое CCASSERT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...