Вопрос

Каковы преимущества и недостатки использования одного вместо другого в C ++?

Это было полезно?

Решение

Если вы хотите узнать истинный ответ, вам следует прочитать Что должен знать каждый специалист по информатике Об арифметике с плавающей запятой.

Короче говоря, хотя double допускает более высокая точность в его представлении, для определенных вычислений это привело бы к более крупные ошибки."Правильный" выбор - это: используйте столько точности, сколько вам нужно, но не больше и выберите правильный алгоритм.

Многие компиляторы в любом случае выполняют расширенную математику с плавающей запятой в "нестрогом" режиме (т.е.используйте более широкий тип с плавающей запятой, доступный в аппаратном обеспечении, например80-битный и 128-битный плавающий), это также следует принимать во внимание.На практике вы можете вряд ли вижу какую-либо разницу в скорости -- в любом случае, они аборигены для аппаратного обеспечения.

Другие советы

Если у вас нет какой-то конкретной причины поступить иначе, используйте double.

Возможно, удивительно, что "обычным" типом с плавающей запятой в C (и C ++) является double, а не float.Стандартные математические функции, такие как грех и журнал принимайте удвоения в качестве аргументов и возвращайте удвоения.Обычный литерал с плавающей запятой, как при написании 3.14 в вашей программе имеет тип double.Не плывет.

На типичных современных компьютерах удвоение может быть таким же быстрым, как и с плавающей запятой, или даже быстрее, поэтому производительность обычно не является фактором, который следует учитывать, даже при больших вычислениях.(И это должно было бы быть Большой расчеты или производительность не должны даже приходить вам в голову.Мой новый настольный компьютер i7 может выполнять шесть миллиардов умножений на удвоения за одну секунду.)

На этот вопрос невозможно ответить, поскольку в вопросе нет контекста.Вот некоторые вещи, которые могут повлиять на выбор:

  1. Компиляторная реализация float, doubles и long doubles.Стандарт C ++ гласит:

    Существует три типа с плавающей запятой:плавающий, двойной и длинный двойной.Тип double обеспечивает по меньшей мере такую же точность, как float, а тип long double обеспечивает по меньшей мере такую же точность, как double.

    Таким образом, все три могут иметь одинаковый размер в памяти.

  2. Наличие FPU.Не все процессоры имеют FPU, и иногда типы с плавающей запятой эмулируются, а иногда типы с плавающей запятой просто не поддерживаются.

  3. Архитектура FPU.FPU IA32 имеет внутренний размер 80 бит - 32-разрядные и 64-разрядные значения с плавающей запятой расширяются до 80 бит при загрузке и уменьшаются при хранении.Существует также SIMD, который может выполнять четыре 32-битных поплавка или два 64-битных поплавка параллельно.Использование SIMD не определено в стандарте, поэтому для этого потребуется компилятор, который выполняет более сложный анализ, чтобы определить, можно ли использовать SIMD, или требует использования специальных функций (библиотек или встроенных компонентов).Результатом 80-битного внутреннего формата является то, что вы можете получать немного отличающиеся результаты в зависимости от того, как часто данные сохраняются в оперативной памяти (таким образом, теряя точность).По этой причине компиляторы не особенно хорошо оптимизируют код с плавающей запятой.

  4. Пропускная способность памяти.Если double требует больше места для хранения, чем float, то для чтения данных потребуется больше времени.Это наивный ответ.В современном IA32 все зависит от того, откуда поступают данные.Если они находятся в кэше L1, нагрузка незначительна при условии, что данные поступают из одной строки кэша.Если он охватывает более одной строки кэша, это приводит к небольшим накладным расходам.Если это из L2, это занимает некоторое время дольше, если это в оперативной памяти, то еще дольше, и, наконец, если это на диске, это огромное время.Таким образом, выбор float или double менее важен, чем способ использования данных.Если вы хотите выполнить небольшое вычисление на большом количестве последовательных данных, предпочтительнее использовать небольшой тип данных.Выполнение большого объема вычислений на небольшом наборе данных позволило бы вам использовать большие типы данных с каким-либо значительным эффектом.Если вы обращаетесь к данным очень случайным образом, то выбор размера данных не имеет значения - данные загружаются в страницы / строки кэша.Таким образом, даже если вам нужен только байт из оперативной памяти, вы могли бы передать 32 байта (это очень зависит от архитектуры системы).Вдобавок ко всему этому, CPU / FPU может быть суперскалярным (он же конвейерный).Таким образом, даже несмотря на то, что загрузка может занять несколько циклов, CPU / FPU может быть занят чем-то другим (например, умножением), что в некоторой степени скрывает время загрузки.

  5. Стандарт не применяет какой-либо конкретный формат для значений с плавающей запятой.

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

Double является более точным, но кодируется в 8 байтах.float равен всего 4 байтам, поэтому меньше места и меньше точности.

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

Я думаю, что именно из-за такого рода ошибок ракета Ariane 6 взорвалась несколько лет назад!!!

Тщательно подумайте о типе, который будет использоваться для переменной

Лично я все время беру двойную дозу, пока не увижу какие-то узкие места.Затем я рассматриваю возможность перехода на float или оптимизации какой-либо другой части

Это зависит от того, как компилятор реализует double .Допустимо, чтобы double и float были одного типа (и это в некоторых системах).

При этом, если они действительно отличаются, то главной проблемой является точность.Двойной имеет гораздо более высокую точность из-за разницы в размерах.Если используемые вами числа обычно превышают значение с плавающей точкой, то используйте double .

Несколько других людей упомянули о проблемах с производительностью.Это было бы как раз последним в моем списке соображений.Корректность должна быть вашим соображением № 1.

Я думаю, независимо от различий (которые, как все отмечают, поплавки занимают меньше места и в целом выполняются быстрее)...кто-нибудь когда-нибудь испытывал проблемы с производительностью при использовании double?Я говорю, используй двойное...и если позже вы решите: "вау, это действительно медленно"...найдите свое узкое место в производительности (вероятно, это не тот факт, что вы использовали double).ЗАТЕМ, если это все еще слишком медленно для вас, посмотрите, где вы можете пожертвовать некоторой точностью и использовать float .

Основное различие между float и double заключается в точности.В Википедии есть больше информации о Одиночная точность (плавающий) и Двойная точность.

Это сильно зависит от процессора, наиболее очевидные компромиссы заключаются между точностью и памятью.С гигабайтами оперативной памяти особых проблем не возникает, поэтому, как правило, лучше использовать doubles.

Что касается производительности, то она сильно зависит от процессора. floats обычно получают лучшую производительность, чем doubles на 32-разрядной машине.На 64 битной, doubles иногда работают быстрее, так как это (обычно) собственный размер.Тем не менее, гораздо большее значение, чем ваш выбор типов данных, будет иметь то, сможете ли вы воспользоваться преимуществами инструкций SIMD на вашем процессоре.

double обладает более высокой точностью, в то время как плавающие значения занимают меньше памяти и работают быстрее.В общем, вам следует использовать float, если только у вас нет случая, когда он недостаточно точен.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top