Вопрос

Несколько лет назад я на собственном горьком опыте узнал о проблемах точности с плавающими числами, поэтому перестал их использовать.Тем не менее, я все еще сталкиваюсь с кодом, использующим числа с плавающей запятой, и это заставляет меня съеживаться, потому что я знаю, что некоторые вычисления будут неточными.

Итак, когда уместно использовать поплавок?

РЕДАКТИРОВАТЬ:Кстати, я не думаю, что встречал программу, в которой точность числа не важна.Но мне было бы интересно услышать примеры.

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

Решение

Короткий ответ:Вам нужно всего лишь использовать плавать когда ты точно знаешь, что делаешь и почему.

Длинный ответ: плавает (в отличие от парный разряд) насколько мне известно, больше не используются за пределами 3D API.Поплавки и двойники имеют одинаковые характеристики производительности на современных процессорах, двойники несколько больше и все.Если сомневаетесь, просто используйте double.

Ах да, и используйте десятичная дробь для финансовых расчетов, конечно.

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

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

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

Во-первых, никогда не используйте числа с плавающей запятой или двойные числа, если вы хотите точно представлять десятичные значения - используйте либо целочисленные типы (int, long и т. д.), либо десятичные (это просто целочисленный тип с коэффициентом масштабирования).Числа с плавающей запятой и двойные числа преобразуются внутри в экспоненциальное представление по базе 2, а числа, точно представленные в экспоненциальном представлении по базе 10, обычно не могут быть представлены точно.(Например, число 10 представляется только приблизительно числами с плавающей запятой или двойными числами).

Во-вторых, с точки зрения точности это зависит от того, что вам нужно.Я не согласен с вашим мнением о том, что никогда не бывает вычислений, в которых точность не имеет значения.Обычно у вас есть конкретная потребность в том, чтобы ваш окончательный результат был точным, скажем, трехзначным.Нет смысла стремиться к максимально возможной точности, если ваши вводимые данные имеют лишь ограниченную точность - скажем, вы взвешиваете около 5 г муки, а ваши весы имеют точность только до 0,5 г.Тем не менее, промежуточные вычисления обычно выигрывают от более высокой точности, но это более важно, чем высокая точность, хотя зачастую и скорость.

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

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

Насколько мне известно, обработка чисел с плавающей запятой поддерживается аппаратно для двойных значений, но не для чисел с плавающей запятой, поэтому использование чисел с плавающей запятой влечет за собой преобразование в двойное число.Однако некоторые процедуры останавливаются раньше при итеративном вычислении значения при передаче числа с плавающей запятой, поскольку это означает, что вам нужна точность только около 8 цифр по сравнению с точностью до 8 цифр.около 16 для парного разряда.

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

float и double очень полезны во многих приложениях. decimal — это дорогостоящий тип данных, и его диапазон (величина наибольшего числа, которое оно может представлять) меньше, чем double.Компьютеры обычно имеют специальную аппаратную поддержку этих типов данных.Они используются много в научных вычислениях.По сути, это основные дробные типы данных, которые вы хотите использовать.Однако в денежных расчетах, где точность чрезвычайно важна, decimal это путь.

Самая распространенная причина, о которой я мог подумать, — это экономия места.Не то чтобы об этом часто стоило беспокоиться, но в некоторых случаях это имеет значение.Число с плавающей запятой занимает вдвое меньше памяти, чем двойное, поэтому вы можете разместить в два раза больше чисел в одном и том же пространстве.Например, у меня был массив чисел, который был слишком большим, чтобы поместиться в ОЗУ как двойные числа, но помещался в массив с плавающей запятой.

На самом деле есть одна вещь, в которой все еще часто использовать поплавки, известные как «единственная точность» с 32 битами:Графические приложения и печать.

Другая причина — видеокарты с их графическими процессорами.Чем меньше дата, тем быстрее операция, потому что необходимо транспортировать меньше битов.Целостные данные имеют проблемы с изображениями с высоким динамическим диапазоном:Глаз способен функционировать в диапазоне светимости 1:10^13 и различает ок.4000 уровней.Таким образом, хотя целочисленные типы данных могут хранить количество уровней, они не могут хранить яркость фона, в то время как у чисел с плавающей запятой нет проблем с этим.На самом деле IEEE 754R позволяет новую «половину точности» плавать с 16 битами и 10 -битной мантиссой, которая теряет некоторую точность, но позволит получить еще большую скорость.OpenGL и DirectX, например.широко использовать поплавки.Глаз очень терпим к артефактам, так что с этим проблем нет.

Все остальные медиа, основанные на графике, наследуют плавающие числа в качестве удобной меры.Мантисса имеет 24 бита, что позволяет выполнить 2^24 = 16,7 миллионов последовательных шагов.Если у вас есть принтер с разрешением DPI 2000, вы все равно можете печатать 213x213 м.Точности более чем достаточно.

Используйте поплавок для производительность и размер.Если вы можете справиться с потерей точности.

Хотя это правда, что современному процессору требуется одинаковое количество времени для обработки операций одинарной и двойной точности, иногда можно получить дважды пропускная способность, если вы используете числа с плавающей запятой с SIMD (MMX/SSE/etc.на x86) инструкции.

Регистры SSE имеют ширину 128 бит и могут хранить 4 поплавка или 2 двойных номера.Таким образом, при правильном использовании с числами с плавающей запятой можно совершать в два раза больше операций, чем с числами типа double.

Уменьшение размера (4 байта вместо 8) становится важным при работе с очень большими наборами данных (а уменьшение размера обычно также повышает производительность из-за кэширования и т. д.).

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