Числа с плавающей точкой фиксированной ширины в C / C ++ - PullRequest
20 голосов
/ 26 августа 2009

int обычно составляет 32 бита, но в стандарте int не обязательно имеет постоянную ширину. Поэтому, если мы хотим 32-битный int, мы включаем stdint.h и используем int32_t.

Есть ли эквивалент для этого для поплавков? Я понимаю, что с поплавками все немного сложнее, поскольку они не хранятся однородным образом, то есть знак, показатель степени, значение и значение. Я просто хочу, чтобы double гарантированно хранился в 64 битах с 1 знаковым битом, 10-битной экспонентой и 52/53-битным значением (в зависимости от того, считаете ли вы скрытый бит).

Ответы [ 6 ]

3 голосов
/ 26 августа 2009

Хотя я не знаю типа, который гарантирует определенный размер и формат, у вас есть несколько вариантов в C ++. Вы можете использовать заголовок <limits> и его шаблон класса std::numeric_limits, чтобы узнать размер данного типа, std::numeric_limits::digits сообщает вам количество битов в мантиссе, а std::numeric_limits::is_iec559 должен сообщить Вы, соответствует ли тип формату IEEE. (Пример кода, который манипулирует числами IEEE на битовом уровне, см. В шаблоне класса FloatingPoint в Google Test gtest-internal.h .)

3 голосов
/ 26 августа 2009

Согласно действующего проекта стандарта C99 , приложение F, оно должно быть двойным. Конечно, это предполагает, что ваши компиляторы соответствуют этой части стандарта.

Для C ++ я проверил черновик 0x и черновик для версии стандарта 1998 года, но ни один из них, похоже, не указывает ничего о представлении, подобном той части стандарта C99, кроме bool в numeric_limits, который указывает, что IEEE 754 / IEC 559 используется на этой платформе, как упоминает Джош Келли.

Очень немногие платформы не поддерживают IEEE 754, хотя - как правило, не окупается разработка другого формата с плавающей запятой, поскольку IEEE 754 четко определен и работает довольно хорошо - и если это поддерживается, то это разумно предположение, что double действительно 64-битный (в конце концов, IEEE 754-1985 вызывает этот формат с двойной точностью, так что это имеет смысл).

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

1 голос
/ 26 августа 2009

Нет изменений в float / double, о которых я знаю. Float всегда был 32-битным, а double - 64. Семантика с плавающей точкой довольно сложна, но в

существуют константы
#include <limits>

boost.numeric.bounds - более простой интерфейс, если вам не нужно все в std :: numeric_limits

1 голос
/ 26 августа 2009

Другая проблема - представление чисел с плавающей запятой. Обычно это зависит от оборудования, на котором вы работаете (но не всегда). Большинство систем используют стандарты IEEE 754 с плавающей запятой, но другие могут также иметь свои собственные стандарты (например, компьютер VAX).

Wikipedia объяснение IEEE 754 http://en.wikipedia.org/wiki/IEEE_754-2008

0 голосов
/ 26 августа 2009

Одна из самых больших проблем с этими типами «фиксированной ширины» заключается в том, что очень легко ошибиться. Вы вероятно не хотели 32-битное целое число. В чем смысл? То, что вы хотели, это целочисленный тип, который может хранить как минимум 1 >> 31. Это long int. Вам даже не нужно <stdint.h> для этого.

Точно так же ваш язык сценариев может реализовывать тип FP, который будет работать, пока базовый C ++ float равен не менее 32 бит Обратите внимание, что это все еще не дает вам точное поведение. Я вполне уверен, что C ++ не гарантирует -1.0/-3.0==1.0/3.0

0 голосов
/ 26 августа 2009

К сожалению, это тоже не гарантировано. Вы должны проверить numeric_limits< T > в <limits>.

Но опять же, я никогда не слышал о реализации, в которой double не было длиной 64 бита. Если бы вы хотели просто предположить, вам, вероятно, это сойдет с рук.

...