2015-10-08 3 views
2

Я пытался простое вычитание значений с плавающей точкой, и я получил странный результат отрицательного нуля:Вычитание значений с плавающей запятой дает отрицательные результаты

var pay = -0.33; 
var res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22); 
res = res.toFixed(2); 
console.log(res); 

выход: -0.00

+5

Что странно об этом? Фактическое число: '-2.7755575615628914e-17'. Это так мало, когда вы конвертируете его в строку через 'toFixed (2)', что результат равен '0,00'. Знак показывает, что он округлен с отрицательного числа. –

+0

Есть уже несколько js парсинга значений float вопросов: http://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript http: // stackoverflow. ком/вопросы/11695618/дилинг-с-флоат-точность в языке JavaScript – BHoft

ответ

0

На самом деле то, что происходит здесь, что есть нет начального положительного числа, большего или равного отрицательному числу. если вы хотите получить положительное значение в результате, то положительное число должно быть больше или равно отрицательному числу . Я пытаюсь сказать: , если вы это сделаете: -0,33-0,11 + 0,44, то вы будете получить положительное нулевое значение, поскольку начальное положительное значение больше всех отрицательных чисел.

1

Ничего странного здесь, это то, как работает плавающая точка IEEE.

Поскольку вы, кажется, здесь делаете форматирование значения валюты, я бы предложил написать функцию повторного использования, чтобы сделать это, чтобы она выполнялась последовательно во всем приложении.

Есть несколько подходов, однако для использования зависит от применения

Это не ошибка. Нет ничего плохого в -0 как значение в плавающей точке IEEE: -0 === 0, x + -0 = x, x * -0 = -0 и т. Д. В арифметике минус 0 работает точно так же, как 0 ,

Обычно я бы обрабатывать -0,00 при форматировании, так как только -0,00 «выглядит странно», -10,20 просто овердрафт :)

res = res.toFixed(2); 
if(res === '-0.00'){ 
    res = '0.00'; 
} 

Я предлагаю эту статью, чтобы понять, IEEE с плавающей точкой лучше: What Every Computer Scientist Should Know About Floating-Point Arithmetic

0

javascript и машина в общей ручке с двойным, как почти бесконечное число.

при округлении до 2 знаков после запятой, javascript дает ближайший округлый номер.

, чтобы исправить это, используйте:

var pay = -0.33; 
var res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22); 
res = res.toFixed(2); 
return (Math.round(res * 100)/100); 

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

EDIT

если изменить круглое число, лучше использовать это:

var fixRound = 2, 
    pay = -0.33, 
    rounding = Math.pow(10, fixRound), 
    res = parseFloat(pay) + parseFloat(0.11) + parseFloat(0.22); 
    res = res.toFixed(fixRound); 
    return (Math.round(res * rounding)/rounding); 

это путь, все, что вам нужно изменить в коде, чтобы оно работало с toFixed (3), toFixed (4), toFixed (5) и т. д., просто установлено значение fixRound - это номер, который вы хотите.

0

Вот решение я нашел, чтобы предотвратить toFixed вернуть отрицательный нуль:

fixed_toFixed = (value, prec) => Math.abs(value) < Math.pow(10, -prec) ? (0).toFixed(prec) : value.toFixed(prec);

Смежные вопросы