Округление JS

Почему js так неправильно округляет

0.49145=0.4914

Предположим, что 5 оно не округляет, тогда

0.491455=0.4915

И это не единственный случай

0.00835=0.0083
0.008355=0.0084

Эта ошибка работает как на
x.toFixed(4);
так и
Math.round (x×1000)/1000;

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Использовал такую либу для работы с денежным форматом github.com/MikeMcl/big.js

Все потому, что вы не используете jQuery. Всегда ипользуйте его, и не будет таких проблем.

что то вы не правду говорите
Math.round(0.00835*10000)/10000 = 0.0084; Math.round(0.49145*10000)/10000 = 0.4915

Ну и в догонку mathjs.org, если сильно хочется точно считать

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

Это еще человек не добрался до
0.2 + 0.1 === 0.3 // false
:D

0.2 + 0.1 === 0.3 // false

Нубский вопрос но это для джаваскрипта потому что:

1) объект != константе (левая часть — объект-результат?)
2) из-за того что в машинном представлении на самом деле левая часть что-то типа 0,298 а правая 0,301 (как в любом адекватном языке при работе с вещественными числами) ??

2) Ну тут даже консоль в браузере поможет. 0.2 + 0.1 = 0.30000000000000004. Просто всё хранится в float64. И отсюда подобные хаки: (0.2*10+0.1*10)/10 = 0.3.

(0.2*10+0.1*10)/10 = 0.3.

А по рукам за такие хаки (так как они не решают проблему точности, хэ-хэ)

Обычно так: ((0.2*10+0.1) — 0,3) <= epsilon)

За такой рефакторинг тоже по рукам давать нужно :)

понятное дело что такой метод не решает все кейсы, это «общий случай» — так как флоаты сравнивают по «приблизительно равно»

Та я про умножение на 10 и отсутствие Math.abs.

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

ДжС (и не только, кстати) хранит числа с плавающей точкой в виде двоичном формате (binary floating point). Этот формат имеет некоторые недостатки, в том числе не умеет точно хранить некоторые числа, вроде 0.1 или 0.2 (так же, как наша десятичная система не может максимально точно хранить числа вроде ⅓ или ⅔). Вот потому и возникают такие казусы.

floating-point-gui.de/basic

Почему js так неправильно округляет

Все правильно

x.toFixed(4);

Как вы могли заметить, он просто не округляет по правилу «если ровно половина, то до большего»

Предположим, что 5 оно не округляет, тогда

«5» тут не при чем. Просто округление до ближайшего целого.

Math.round (x×1000)/1000;

А с round все нормально. Только замените 1000 на 10000, чтобы ваш пример имел смысл

о чем речь?

>> 0.49145
<- 0.49145
>> 0.49145 === 0.4914
<- false
>> 0.49145 == 0.4914
<- false
>> 0.49145  * 1000
<- 491.45

Подписаться на комментарии