使用数学 Javascript 的舍入问题
Rounding Issue with Javascript using Math
我正在做一个项目,我有一个输入字段,用户可以在其中输入美元金额,然后根据他们想要支付的频率将该金额除以所述值(2、4 或 12) ).因此,例如,如果我输入 5 美元并将频率设置为 2,我将让它显示 2.50 美元的费用金额。我遇到的问题是,如果用户输入 20.27 美元,频率设置为 2,我希望显示的是 10.14 美元,但出于某种原因,即使在使用 Math.round
和 toFixed(2)
后我也会得到 10.13 美元。如果我输入 2.27 美元或 0.27 美元,我确实会分别得到预期的 1.14 美元和 .14 美元,但一旦超过 10 美元,它就不再正确舍入。我不知道我做错了什么。这是我的代码:
const setAmount = (num) => {
scope.selectAmount(selectedAmount / num);
finalAmount = ((Math.round(selectedAmount * 100) / 100) / num).toFixed(2);
selectedAmountText = '$' + finalAmount;
$('#pay-schedule span').text(selectedAmountText);
}
如有任何帮助,我们将不胜感激。谢谢!
更改顺序如下:
finalAmount = ((Math.round(selectedAmount / num * 100) / 100)).toFixed(2);
稍后再划分会把事情搞砸。
我对此没有确切的解释,但最后除以 2 会使它有些不一致。因此,首先将数字除以 2 可以解决您提供的特定值的问题。
function round(num) {
let val = num / 2
return (Math.round(val * 100) / 100).toFixed(2);
}
我不确定你为什么需要 toFixed()
。
var amount=20.27;
var frequency=2;
var finalamount=amount/frequency;
finalamountrounded=Math.round(finalamount * 100) / 100
console.log(finalamountrounded)
生产
10.14
问题是,数字 20.27 不存在。输入时四舍五入到最接近的可能值:
var a = 20.27;
a.toFixed(18) // output: "20.269999999999999574"
var b = a/2;
b.toFixed(18); // output: "10.134999999999999787"
我使用 toFixed(18)
因为它显示了所有相关数字。从这个角度来看,10.13
是正确的预期值。
使用 Math.round(b*100)/100
舍入可能会解决此示例,但会产生其他错误。这里 b*100 四舍五入到下一个整数。在这种情况下,除以 100 returns 一个值 >10.14
(不是 =10.14
)。
c = Math.round(b*100);
c.toFixed(18); // output: "1014.000000000000000000"
(c/100).toFixed(18); // output: "10.140000000000000568"
这个数字问题在所有支持 IEEE 浮点数的语言中都很常见。这就是财务软件使用美分或例如BCD(二进制编码的十进制)数字。这就是旧编程语言 COBOL 用于许多财务程序的原因。
我正在做一个项目,我有一个输入字段,用户可以在其中输入美元金额,然后根据他们想要支付的频率将该金额除以所述值(2、4 或 12) ).因此,例如,如果我输入 5 美元并将频率设置为 2,我将让它显示 2.50 美元的费用金额。我遇到的问题是,如果用户输入 20.27 美元,频率设置为 2,我希望显示的是 10.14 美元,但出于某种原因,即使在使用 Math.round
和 toFixed(2)
后我也会得到 10.13 美元。如果我输入 2.27 美元或 0.27 美元,我确实会分别得到预期的 1.14 美元和 .14 美元,但一旦超过 10 美元,它就不再正确舍入。我不知道我做错了什么。这是我的代码:
const setAmount = (num) => {
scope.selectAmount(selectedAmount / num);
finalAmount = ((Math.round(selectedAmount * 100) / 100) / num).toFixed(2);
selectedAmountText = '$' + finalAmount;
$('#pay-schedule span').text(selectedAmountText);
}
如有任何帮助,我们将不胜感激。谢谢!
更改顺序如下:
finalAmount = ((Math.round(selectedAmount / num * 100) / 100)).toFixed(2);
稍后再划分会把事情搞砸。
我对此没有确切的解释,但最后除以 2 会使它有些不一致。因此,首先将数字除以 2 可以解决您提供的特定值的问题。
function round(num) {
let val = num / 2
return (Math.round(val * 100) / 100).toFixed(2);
}
我不确定你为什么需要 toFixed()
。
var amount=20.27;
var frequency=2;
var finalamount=amount/frequency;
finalamountrounded=Math.round(finalamount * 100) / 100
console.log(finalamountrounded)
生产
10.14
问题是,数字 20.27 不存在。输入时四舍五入到最接近的可能值:
var a = 20.27;
a.toFixed(18) // output: "20.269999999999999574"
var b = a/2;
b.toFixed(18); // output: "10.134999999999999787"
我使用 toFixed(18)
因为它显示了所有相关数字。从这个角度来看,10.13
是正确的预期值。
使用 Math.round(b*100)/100
舍入可能会解决此示例,但会产生其他错误。这里 b*100 四舍五入到下一个整数。在这种情况下,除以 100 returns 一个值 >10.14
(不是 =10.14
)。
c = Math.round(b*100);
c.toFixed(18); // output: "1014.000000000000000000"
(c/100).toFixed(18); // output: "10.140000000000000568"
这个数字问题在所有支持 IEEE 浮点数的语言中都很常见。这就是财务软件使用美分或例如BCD(二进制编码的十进制)数字。这就是旧编程语言 COBOL 用于许多财务程序的原因。