2009-04-15 4 views
15

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

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

+0

Что именно вы делаете? Вы ищете полностью переносимый способ взять восемь байтов и интерпретировать их как 64-битный номер с плавающей запятой стандарта IEEE? –

+2

@ Давид: Да, это именно то, что я делаю. Я где-то нашел что-то, что C++ плавает, а парные - в формате IEEE-754.Я не был уверен, что двойники всегда использовали ту же точность и хотели добавить к ней чек. – Whatsit

+0

Теперь я не уверен, что моя оригинальная информация была правильной. Какая здесь конвенция? Должен ли я удалить этот вопрос и добавить еще один вопрос о преобразовании из IEEE-754? – Whatsit

ответ

11

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

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

или

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

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

+0

Это неверно предполагает, что char имеет размер как байт. – 2009-04-16 06:51:19

+4

um, нет, это совсем не так. sizeof возвращает в единицах символов. CHAR_BIT определяется как количество бит на символ. умножьте sizeof (x) на CHAR_BIT, и у вас есть * точно * сколько битов x. –

+0

Так, например, на x86 CHAR_BIT определяется как 8. sizeof (double) return 8. (8 * 8) == 64. –

4

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

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

Если дважды не 64 бита, то код будет похож

char a[0]; 

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

+0

байту не гарантируется 8 бит –

+0

@Evan: Интересный момент. Добавьте «&& (unsigned char) 255 == 255 && (unsigned char) 256 == 0" к условию, чтобы проверить, что символы имеют 8 бит. –

+1

Как насчет случая, когда размер double равен 16 байтам, но байт состоит из 4 бит? –

6

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

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

+1

80-битные удваивают Intel-ism, и true, только если FPU фактически находится в 80-битном режиме (есть также 64-битный режим) ... – DevSolar

+0

Я знаю, но тем не менее ... –

+0

И даже 32-битный режим в зависимости от того, как вы инициализируете Direct3D. –

1

См. this post для аналогичной проблемы и утверждения времени компиляции, не поддерживающего CCASSERT.

22

В 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++.

+0

Это еще лучшее решение, чем я надеялся. Принял ответ Эвана, однако, поскольку он отвечает на вопрос, поскольку он существует. Я просто задал неправильный вопрос. – Whatsit

6

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

Смежные вопросы