Обеспечение двойного 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
является ключевым словом.