почему такой код

Выделить код

Код:

alert((0.144) * 100);

выдаёт такое число : 14.399999999999999 ?
из курса математики помню, что должно получиться 14.4 :)
протестил на 4х браузерах с 2-х компов: Opera, Chrome, Fx, показывают 14.399999999999999, ie - 14.399999999999998

Это все от округления при вычислениях.

Выделить код

Код:

alert(0.01/0.03 == 1/3);

http://javascript.ru/ecmascript/part4#a-4.3.20
http://ru.wikipedia.org/wiki/%D0%A7%D0% … 1%82%D0%B8
http://ru.wikipedia.org/wiki/%D0%A7%D0% … 0.BE.D0.BD

01-03-2009 02:45:04
А для точных вычислений требуются инструменты посерьезнее.

А в названии темы - орфографическая

получается что обычный калькулятор - непосильная задача для js? или есть какие то решения?

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

Учить матчасть
http://xpoint.ru/know-how/Articles/FloatingPointNumbers?5

patt пишет

http://xpoint.ru/know-how/Articles/FloatingPointNumbers?5

протестил на 4х браузерах с 2-х компов: Opera, Chrome, Fx, показывают 14.399999999999999, ie - 14.399999999999998

Вообще-то

Выделить код

Код:

14.4==14.3(9)

, а в силу конечности регистров (и памяти) компьютеров получаем и

Выделить код

Код:

14.4==14.399999999999999

:)
Так что только Осёл не справился с заданием:D

Если же нужна математическая точность, то и программы для этого надо использовать математические ;)

Forest

Выделить код

Код:

(0.144*100).toPrecision(25)
Shura пишет

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

я в курсе, что такая проблема есть, но то, что обычные проценты по вкладам js посчитает не правильно было сюрпризом ) другие языки с этой проблемой справились, перед там, как запостить тему проверил на java и php.

patt пишет

обычные проценты по вкладам js посчитает не правильно

js посчитал правильно. Попробуйте написать 14.4 в шестнадцатиричном (или двоичном) виде и увидите, в чем грабли :)
Проценты по вкладам? Сколько надо знаков после запятой оставить? Два? Тогда так, например:

Выделить код

Код:

alert(Math.round(14.39999 * 128)/128);

или то же, но сдвигами влево-вправо.
Будет правильно работать даже в самых древних браузерах (как всегда, кроме осла - тот младше IE 4 может слегка врать =) )

Или так, скажем:

Выделить код

Код:

var x=число, которое мы округляем.
var n=число знаков после запятой, которое нам надо получить.
var s; // тут будет строковое представление числа, готовое для вывода с нужной точностью

s=String(Math.round(x*Math.pow(10, n)));
s=s.substr(0,s.length-n)+"."+s.substr(s.length-n-1);

Надо нам три знака после запятой - забиваем n=3; x=14.399999999
В первой строке x умножится на 1000, потом округлится и преобразуется в строку "14400", вторая строчка сделает из него "14.400". Вот и всё :)

alex_past пишет

js посчитал правильно.

заказчик почему то с вами не согласился :)

p.s. Всем спасибо за подробное объяснение проблемы и вариантов решения.

patt

я в курсе, что такая проблема есть, но то, что обычные проценты по вкладам js посчитает не правильно было сюрпризом ) другие языки с этой проблемой справились, перед там, как запостить тему проверил на java и php.

Эта проблема к языкам имеет мало отношения, так как как правило проблема именно в МАШИННОМ округлении.
То, что конкретный пример на одном языке получился, а на другом нет, мб простым везением.
Тут надо использовать либо библиотеки для финансовых вычислений/работы с произвольной точностью/символьных вычислений, либо специально созданные языки (тот же COBOL), ну или просто использовать самые "длинные" типы данных + оптимизировать вычисление выражений с тз финальной погрешности (наверняка они все простые и их не так много).