2009-08-26 3 views
14

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

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

+0

Как правило, количество бит для int необходимо, поскольку оно кодирует некоторые типы флагов объектов. Зачем вам нужны заверения в точности ваших поплавков? В большинстве случаев я видел, как люди склонны переоценивать важность размеров случайных величин. Часто вам будет лучше использовать размер слова по умолчанию для машины, чем пытаться выжать 3 байта памяти или произвольно использовать 32-битные значения. –

+0

@ Andrew-Khosravian Я пишу скриптовый язык, и я хотел бы иметь возможность предоставлять гарантии размера шрифта для моих пользователей. Это делает код, написанный на моем языке сценариев более переносимым. – Imagist

+2

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

ответ

3

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

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

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

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

+0

Как насчет в C++? – Imagist

+0

Я не согласен с тем, что IEEE 754 работает очень хорошо, он хорошо укоренился, поэтому не так много можно сделать о ot. Я согласен с тем, что вам нужно удвоить, и вы хотите добавить проверку работоспособности, которая не удастся, если кто-то найдет компилятор с двойным размером, который является неправильным размером. –

+0

@ dwelch: Я не говорю, что у него нет своей доли проблем или что это всегда лучший выбор, но если у вас нет необходимости быть предельно точной или иначе иметь очень специализированные потребности, когда дело доходит до плавающих, точка, IEEE 754 имеет тенденцию делать трюк, не будучи исключительно медленным. –

0

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

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

1

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

Википедии из объяснений IEEE 754 http://en.wikipedia.org/wiki/IEEE_754-2008

1

Там нет различия в обращении/вдвое больше, чем я знаю. Поплавок имеет уже 32 бит для возрастов и дважды был 64. Плавающих точки семантики довольно сложна, но существует константы в

#include <limits> 

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

+0

Это неверно на всех платформах. – Imagist

+0

Я видел один компилятор (LCC?), Который сделал 64-битные типы 'float' и' double'. – dan04

3

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

-3

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

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

+0

Нет, я определенно хочу 32-битное целое число. Существует множество языков, которые предоставляют гарантии относительно размеров их основных типов (C# и Java - два примера). «Точка», как вы ее называете, является последовательным поведением на всех платформах. – Imagist

+0

Простите, но вам не хватает точки. Вы хотите, чтобы ваш язык сценариев имел точно 32-битный тип.Это никоим образом не требует использования типа C++, имеющего ровно 32 бита. Вероятно, вы также хотите гарантированное переполнение, гарантированное поведение% и т. Д. Таким образом, вы все равно будете переопределять математику. Тогда тривиально сделать это matah по модулю 2^32. – MSalters

+1

Нет, это 'int_least32_t', * not *' long int'. – dan04

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