2012-03-02 4 views
2

Я использовал sizeof для проверки размеров длин и плавок в моей машине 64 bit amd opteron. И показать, как 4.Floats and Longs

Когда я проверяю limits.h и float.h для максимального поплавка и длинных значений этих значений я получаю:

Max value of Float:340282346638528859811704183484516925440.000000 

Max value of long:9223372036854775807 

Поскольку они оба имеют один и тот же размер, как можно поплавок магазин такое огромное значение по сравнению с длинным?

Я предполагаю, что у них есть другое представление хранилища для float. Если это так, влияет ли это на производительность: т. Е. Использует longs быстрее, чем использование float?

+0

Что-то не так. Если 'sizeof (long) == 4', то максимальное значение' long' должно быть только «2147483647». – Mysticial

+0

Длинное значение неверно только для 32 бит. Это должно быть только около 2 миллиардов. – ldav1s

+2

Некоторые 64-битные ABI имеют 32-битные длинные и 64-битные длинные длинные - другие используют 64 бита для обоих. – Perry

ответ

6

Это компромисс.

32 битное целое число можно выразить каждое целое число от -2 и +2 -1.

32-битный float использует экспоненциальную нотацию и может выражать гораздо более широкий диапазон чисел, но не сможет выразить все числа в диапазоне - даже не все целые числа. Он использует некоторые из битов для представления дробной части, а остальные - для экспоненты. Фактически это двоичный эквивалент обозначений типа 6.023 * 10 или что у вас есть, с расстоянием между представимыми числами, довольно большими на концах диапазона.

Для получения дополнительной информации, я бы прочитал эту статью, «Что каждый компьютер ученый должен знать о арифметики с плавающей точкой» Дэвид Голдберг: http://web.cse.msu.edu/~cse320/Documents/FloatingPoint.pdf

Кстати, на вашей платформе, я ожидал бы, что поплавок будет 32-битное количество и длинное количество бит в 64 бит, но это не очень важно для общей точки.

Рабочие характеристики здесь трудно определить. Операции с плавающей запятой могут или не могут занимать значительно больше целых операций в зависимости от характера операций и использования аппаратного ускорения для них. Как правило, операции, такие как сложение и вычитание, намного быстрее в целых числах - умножение и деление меньше. В какой-то момент люди, пытающиеся выкачать каждый цикл при выполнении вычислений, будут представлять действительные числа как арифметику с фиксированной точкой и использовать целые числа, чтобы представлять их, но этот вид трюка гораздо реже. (На Opteron, например, вы используете, арифметика с плавающей запятой действительно аппаратно ускоряется.)

Почти все платформы, на которых работает C, имеют различные «плавающие» и «двойные» представления, причем «двойные» поплавки являются двойной точностью , то есть представление, которое занимает в два раза больше бит. В дополнение к космическому компромиссу, операции с ними часто несколько медленнее, и, опять же, люди, очень обеспокоенные производительностью, будут пытаться использовать float, если точность их вычисления не требует удвоения.

0

Математика с плавающей точкой является предметом для себя, но да: типы int обычно быстрее, чем типы float.

Один трюк, который нужно помнить, заключается в том, что не все значения могут быть выражены как поплавок. , например. наиболее близким вам может быть 1,9 1,899999999. Это приводит к забавным ошибкам, когда вы говорите, что (v == 1.9) все происходит неожиданно!

+0

Дело в том, что я использую только целые числа (а не десятичные числа). Мне нужно выразить числа, которые больше целых. Так долго это идеальный путь. Но по какой-то причине библиотека, которую я использую, терпит неудачу, когда я использую longs .. но она отлично работает, когда использует float. Поэтому я стараюсь использовать float вместо longs. Будут ли поплавки пропустить хранилище целых чисел? –

+0

Любой вызов API будет принимать только один тип номера. Если вам интересно, почему он сбой, когда вы кормите его неправильным типом данных, я бы предположил, что вы не можете понять, как работает система типа C, - может потребоваться потратить некоторое время на чтение, потому что это не единственное место, где у вас будут проблемы с этим. – Perry

+0

@ TheFlyingDutchman: Терминология важна. Вам не нужно выражать числа, которые длиннее * целых чисел * (таких чисел нет), вам нужно выразить числа, которые длиннее, чем 'int'. 'int '- один из нескольких целых типов. 'long' - это еще один. –

0

Если да, то это влияет на производительность: т. Е. Использует длинные функции быстрее, чем использование поплавков?

Да, арифметика с long с будет быстрее, чем с float с.

Я предполагаю, что у них есть другое представление хранилища для поплавка.

Да. Типы float представлены в формате IEEE 754 (single precision).

Поскольку они оба имеют одинаковый размер, как может флоат хранить такое огромное значение по сравнению с длинным?

Он оптимизирован для хранения чисел в нескольких точках (например, около 0), но он не оптимизирован для обеспечения точности. Например, вы можете добавить 1 к 1000000000. С float, вероятно, не будет никакой разницы в сумме (1000000000 вместо 1000000001), но с long будет.

+0

Это не * обязательно * случай, когда 'long' арифметика будет быстрее, чем арифметика' float'. Некоторые системы сильно оптимизированы для плавающей запятой. –

+0

@ Keith Thompson, правда, но я предполагаю, что AMD Opteron, заявленный OP, не является одним из них. – ldav1s

1

Маловероятно, чтобы операции на long были быстрее операций на float, или наоборот.

Если вам нужно представлять только целые числа, используйте целочисленный тип. Какой тип, который вы должны использовать, зависит от того, для чего вы его используете (подписанный против unsigned, short против int против long против long long, или один из типов точной ширины в <stdint.h>).

Если вам нужно представить действительные цифры, используйте один из типов с плавающей запятой: float, double, или long double. (float фактически не используется много, если объем памяти не в почете, double имеет более высокую точность и часто не медленнее, чем float.)

Короче говоря, выбрать тип которого семантика соответствует тому, что вам нужно, и беспокоиться о производительности позже , Нет ничего выгодного в получении неправильных ответов быстро.

Что касается представления хранилища, другие ответы в значительной степени охватывают это. Обычно целые без знака используют все свои биты для представления значения, целые числа со знаком выделяют один бит для представления знака (хотя обычно это не напрямую), а типы с плавающей точкой выделяют один бит для знака, несколько бит для экспоненты, а остальные для значения. (Это грубое упрощение.)