2017-01-18 11 views
3

Javascript неправомерно изменяет результат простого умножения. Как я могу это исправить?

function roundUp(num, precision) { 
 
    return Math.ceil(num * precision)/precision; 
 
} 
 

 
var num = 0.07; 
 
var precision = 100; 
 
console.log(roundUp(num, precision));

Когда аргументы функции является 0,07 и 100, «Num * точность» умножение дает что-то вроде «+7,000000000001» и функция CEIL округляет до 8. И я получаю совершенно другой результат без причины.

Как это исправить? У меня есть big.js, но я не мог это решить.

+2

http://0.30000000000000004.com/ – cartant

+0

какой результат будет там? –

+0

Посмотрите на это: http://stackoverflow.com/questions/3072307/what-is-the-standard-solution-in-javascript-for-handling-big-numbers-bignum – ppasler

ответ

0

Другая наивная попытка здесь как функции - это потолок. Это приводит к тому, что коэффициент ошибки уменьшает число на EPSILON раз, поэтому мы получаем 6.9999999 .. вместо 7.00000000..1

Опять же наивная попытка!

function roundUp(num, precision) { 
 
     return Math.ceil((num * precision) - (num * precision * Number.EPSILON))/precision; 
 
} 
 

 
console.log(roundUp(0.07, 100)) 
 
console.log(roundUp(0.03, 100)) 
 
console.log(roundUp(0.002, 1000)) 
 
console.log(roundUp(0.00222, 1000)) 
 
console.log(roundUp(0.006, 1000)) 
 
console.log(roundUp(0.00600000000000000000001, 10000000000000000000));//broken 
 
console.log(roundUp(0.006001, 10000000)); 
 
console.log(roundUp(0.0333, 1000)) 
 
console.log(roundUp(0.07777777, 10)) 
 
console.log(roundUp(0.07777777, 100)) 
 
console.log(roundUp(0.07777777, 1000)) 
 
console.log(roundUp(0.07777777, 10000)) 
 
console.log(roundUp(0.07777777, 100000)) 
 
console.log(roundUp(0.07777777, 1000000)) 
 

 
console.log(roundUp(0.33333333333333, 1000000))

+0

Это может обеспечить «правильное» значение в случае OP, но, безусловно, неправильные "значения в некоторых других случаях из-за плавающих математических недостатков. Кроме того, было бы крайне неэффективно преобразовывать каждое число в строку, а затем обратно в число. –

+0

Ваше использование toFixed глупо; вы преобразовываете число в строку base-10, а затем сразу же возвращаете его обратно к плаву base-2. В лучшем случае вам повезло и получить его, чтобы обойти другой путь, когда он отступает, но это просто случайно. – Dave

+0

@ Андрюкляревский, Дейв Я согласен с обоими вашими наблюдениями. Обычно я вижу, что коэффициент EPSILON может составлять 10-12 десятичных цифр, поэтому наивная попытка отказаться от этой части. Я уверен, что это не так точно, как вы, ребята, упомянули. – sabithpocker