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

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

CalculateTotalTax = function (TaxRate, TaxFreePrice) {
     return ((parseFloat(TaxFreePrice) / 100) * parseFloat(TaxRate)).toFixed(4);
};

Мне не удалось ввести какие-либо два значения, которые вызвали для меня неправильный результат для этого метода. Если я уберу toFixed (4), я смогу увидеть, где вычисления начинают терять точность (где-то около 6-го знака после запятой). Сказав, что, хотя, я понимаю, что числа с плавающей запятой иногда могут быть не в состоянии быть представленными, или я неправильно понял, и может всегда быть точно представлены 4 десятичных знака (например).

MSDN объясняет плавания кактакие...

Это означает, что они не могут содержать точное представление любой величины, которая не является двоичной дробью (в форме k / (2 ^ n), где k и n являются целыми числами)

Теперь я предполагаю, что это относится ко всем числам с плавающей точкой (включая те, которые используются в javascript).

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

Надеюсь, то, что я спрашиваю, имеет смысл.

 Uwe Keim12 янв. 2011 г., 03:03
Может быть, это связано с этой темой:en.wikipedia.org/wiki/Machine_epsilon
 MarkJ12 янв. 2011 г., 10:25
Тони Пони, также известен какДжон Скитимеетотличное объяснение, Читаемый, понятный, забавный, не раздражающий и не такой тяжелый, какнекоторые ссылки которые часто публикуются на эту тему.

Ответы на вопрос(4)

. Если вы на самом деле используете денежные значения в своем коде (как в вашем примере), вы должны предпочесть десятичные типы (System.Decimal в .Net). Это позволит избежать некоторых проблем округления при использовании чисел с плавающей запятой и лучше соответствовать домену.

которые вы должны учитывать при работе с поплавками:

1- Вы должны знатьмашина эпсилон, Чтобы узнать, сколько у вас точности.

2- Выне следует предполагатьесли два значения равны в базе 10, они равны в базе 2 в машине с пределом точности.

if ((6.0 / 10.0) / 3.0 != .2) {
        cout << "gotcha" << endl;
}

Число 2 может быть достаточно убедительным, чтобы избежать сравнения чисел с плавающей запятой на равенство, вместо этого для сравнения можно использовать порог и операторы больше или меньше

 Nylon Smile21 окт. 2013 г., 23:11
Спасибо @Shedal. Исправил ответ.
 Dmytro Shevchenko08 окт. 2013 г., 16:05
Причина.1 != 1/10 это потому что1/10 == 0, Вы используете целочисленное деление.
 Stephen Canon12 янв. 2011 г., 03:28
Число 2 не означает, что вы «никогда не должны сравнивать числа с плавающей точкой на равенство»; в конце концов, с такой же легкостью следует, что вы никогда не должны сравнивать десятичные числа на равенство. Это означает, что нельзя писать код, который не понимаешь. Потратьте время, чтобы узнать, как работает с плавающей точкой.
 Nylon Smile12 янв. 2011 г., 04:24
Как вы сказали, нужно учиться с плавающей точкой; что-то вроде (0,1 == 1/10) выглядит настолько невинно, что никто, вероятно, не подумает, что это вызывает ошибку, если он не читал об этом раньше. Даже если говорить об основах математики, мало кто знает, что 10 = 9,999 ... или как преобразовать десятичное число в двоичное.
Решение Вопроса

Что каждый ученый должен знать о плавающей точке: http://docs.sun.com/source/806-3568/ncg_goldberg.html

Краткий ответ: числа с плавающей запятой двойной точности (которые по умолчанию в JavaScript) имеют точность около 16 десятичных знаков. Округление может варьироваться от платформы к платформе. Если абсолютно необходимо, чтобы вы получали последовательно правильный ответ, вы должны самостоятельно сделать рациональную арифметику (это не должно быть сложно - для валюты, может быть, вы можете просто умножить на 100, чтобы сохранить количество центов в виде целого числа).

Но если достаточно получить ответ с высокой степенью точности, поплавки должны быть достаточно хорошими, особенно с двойной точностью.

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

Попробуйте 1 * 3, или 162,295 / 10, или 24,0 + 47,98. Те, которые терпят неудачу для меня в JS. Но 24.0 * 47.98 не подводит.

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

Ваш ответ на вопрос