11 ответов:
Если вы хотите знать истинный ответ, вы должны прочитать Что Каждый Компьютерный Ученый Должен Знать Об Арифметике С Плавающей Запятой.
короче, хотя
doubleпозволяет более высокая точность в своем представлении, для определенных вычислений он будет производить больше ошибок. "Правильный" выбор:используйте столько точности, сколько вам нужно, но не больше и выберите правильный алгоритм.много компиляторы все равно делают расширенную математику с плавающей запятой в "нестрогом" режиме (т. е. используют более широкий тип с плавающей запятой, доступный в аппаратных средствах, например, 80-бит и 128-бит с плавающей запятой), это также следует учитывать. На практике, вы можете почти не вижу разницы в скорости -- они все равно являются уроженцами аппаратного обеспечения.
Если у вас нет какой-то конкретной причины, чтобы сделать иначе, используйте double.
возможно, удивительно, что это double, а не float, который является "нормальным" типом с плавающей запятой в C (и C++). Стандартные математические функции, такие как грех и log возьмите двойники в качестве аргументов и верните двойники. Обычный литерал с плавающей запятой, как при написании 3.14 в вашей программе есть тип double. Не плавать.
на типичных современных компьютеров, двойники могут быть такими же быстрыми, как поплавки, или даже быстрее, поэтому производительность обычно не является фактором, который следует учитывать, даже для больших вычислений. (И это должно быть большой расчеты или производительность даже не должны входить в ваш ум. Мой новый настольный компьютер i7 может сделать шесть миллиардов умножений двойников за одну секунду.)
на этот вопрос невозможно ответить, так как нет контекста для вопроса. Вот некоторые вещи, которые могут повлиять на выбор:
реализация компилятора поплавков, двойников и длинных двойников. Стандарт C++ гласит:
есть три типа с плавающей запятой: float, double и long double. Тип double обеспечивает по крайней мере такую же точность, как float, а тип long double обеспечивает по крайней мере такую же точность, как double.
Итак, все три могут быть одинакового размера в памяти.
наличие ФПУ. Не все процессоры имеют FPU, и иногда типы с плавающей запятой эмулируются, а иногда типы с плавающей запятой просто не поддерживаются.
архитектура FPU. FPU IA32 80bit внутренне-32 бита и поплавки 64 битов расширены к 80bit на нагрузке и уменьшены на магазине. Есть также инструкции, которые могут сделать четыре 32бит или 64бит двух поплавков поплавки параллельно. Использование SIMD не определено в стандарте, поэтому потребуется компилятор, который выполняет более сложный анализ, чтобы определить, можно ли использовать SIMD, или требует использования специальных функций (библиотек или встроенных функций). Результатом 80-битного внутреннего формата является то, что вы можете получить немного разные результаты в зависимости от того, как часто данные сохраняются в ОЗУ (таким образом, теряя точность). По этой причине компиляторы не оптимизируют код с плавающей запятой особенно что ж.
пропускная способность памяти. Если double требует больше памяти, чем float, то для чтения данных потребуется больше времени. Это наивный ответ. На современном IA32 все зависит от того, откуда поступают данные. Если он находится в кэше L1, нагрузка незначительна при условии, что данные поступают из одной строки кэша. Если он занимает более одной строки кэша есть небольшие накладные расходы. Если это из L2, это займет некоторое время, если это в оперативной памяти, то это еще дольше и, наконец, если это на диске это огромное время. Таким образом, выбор float или double менее важен, чем способ использования данных. Если вы хотите сделать небольшой расчет на большом количестве последовательных данных, предпочтителен небольшой тип данных. Выполнение большого количества вычислений на небольшом наборе данных позволит вам использовать большие типы данных с любым значительным эффектом. Если вы получаете доступ к данным очень случайным образом, то выбор размера данных не имеет значения - данные загружаются в страницы / строки кэша. Поэтому, даже если вам нужен только байт из ОЗУ, вы может быть передано 32 байта (это очень зависит от архитектуры системы). Кроме того, CPU/FPU может быть супер-скалярным (он же конвейерный). Таким образом, даже если загрузка может занять несколько циклов, CPU/FPU может быть занят чем-то другим (например, умножением), что в определенной степени скрывает время загрузки.
стандарт не применяет какой-либо определенный формат для значений с плавающей запятой.
Если у вас есть спецификация, после этого то направит вас к оптимальному выбору. В противном случае, это опыт, как использовать.
Double является более точным, но кодируется по 8 байт. поплавок составляет всего 4 байта, поэтому меньше места и меньше точности.
вы должны быть очень осторожны, если у вас есть double и float в вашем приложении. У меня была ошибка из-за этого в прошлом. Одна часть кода использовала float, в то время как остальная часть кода использовала double. Копирование double to float, а затем float to double может вызвать ошибку точности, которая может иметь большое влияние. В моем случае, это был химический завод... надеюсь, у него не было драматические последствия :)
Я думаю, что именно из-за такого рода ошибки ракета Ariane 6 взорвалась несколько лет назад!!!
тщательно подумайте о типе, который будет использоваться для переменной
Я лично иду на удвоение все время, пока не увижу некоторые узкие места. Затем я рассматриваю возможность перехода к плаванию или оптимизации какой-либо другой части
Это зависит от того, как компилятор реализует двойной. Это законно для double и float быть того же типа (и это на некоторых системах).
Это, как говорится, если они действительно разные, то главный вопрос-точность. Двойник имеет гораздо более высокую точность из-за его разницы в размере. Если числа, которые вы используете, обычно превышают значение float, используйте double.
несколько других людей упомянули производительность issues. Это было бы точно последний в моем списке соображений. Правильность должна быть вашим # 1 соображением.
используйте любую точность, необходимую для достижения соответствующих результатов. Если вы обнаружите, что ваш код не работает так хорошо, как вы хотели бы (вы использовали профилирование правильно?) взгляните на:
Я думаю, что независимо от различий (которые, как все указывают, поплавки занимают меньше места и в целом быстрее)... кто-нибудь когда-нибудь испытывал проблемы с производительностью, используя double? Я говорю использовать двойной... и если позже вы решите "Вау, это очень медленно"... найдите свое узкое место в производительности (что, вероятно, не тот факт, что вы использовали double). Затем, если он все еще слишком медленный для вас, посмотрите, где вы можете пожертвовать некоторой точностью и использовать float.
это сильно зависит от процессора наиболее очевидные компромиссы между точностью и памяти. С GBs оперативной памяти, память не является большой проблемой, так что, как правило, лучше использовать
doubles.что касается производительности, то она сильно зависит от процессора.
floatы, как правило, получит более высокую производительность, чемdoubles на 32-битной машине. На 64 бит,doubleиногда быстрее, так как это (обычно) родной размер. Тем не менее, что будет иметь значение гораздо больше, чем ваш выбор типов данных независимо от того, можете ли вы воспользоваться инструкциями SIMD на своем процессоре.
double имеет более высокую точность, тогда как поплавки занимают меньше памяти и быстрее. В общем, вы должны использовать float, если у вас нет случая, когда он недостаточно точен.
главным образом разница между поплавком и двойником точность. В Википедии есть более подробная информация о один (float) и двойной точности.
Comments