JavaScript 定时循环舍入错误
JavaScript timed loop rounding error
timedLoop(10000, function() {
health=health-0.1;
updatecounters();
console.log(health);
});
Health 最初设置为 83.3,console.log 打印出以下语句:
83.2
83.10000000000001
83.00000000000001
82.90000000000002
82.80000000000003
82.70000000000003
82.60000000000004
82.50000000000004
82.40000000000005
它应该每 10 秒减少 0.1,但似乎存在浮点错误。我知道我可以通过简单地将变量四舍五入到小数点后两位来解决这个问题,但为什么会这样?
我认为这只是糟糕的编译。如果一个数字有一个终止小数点(少于 32 位)或者是有理数,程序应该能够存储准确的值而不是让像这样的恶作剧发生。我完全理解为什么乘法和除法会导致浮点错误,但是加法和减法不应该导致这样的错误。
可以在减法后的数上调用.toFixed
let health = 83.3;
setInterval(function() {
health = (health - 0.1).toFixed(1);
console.log(health);
}, 500);
但是,.toFixed
会将数字转换为字符串,如果需要将其保留为数字,可以用数字构造函数包装代码:
Number((health - 0.1).toFixed(1));
问题不在于 javascript,但它适用于所有浮点计算,因为 0.1、0.2 和 0.3 不能完全表示。
Check this link了解更多
浮点问题只是生活的一部分。你需要学会和他们一起生活。
你可以试试:
// health (String) is for display, can be values from 100.0 to 0.1
var health = "100.0";
// healthMath (Int) is for calculations. It is an int, not a float.
var healthMath = 1000;
因此,在您的示例中:
timedLoop(10000, function() {
healthMath -= 1;
health = (healthMath / 10).toFixed(1);
updatecounters();
console.log(health);
});
timedLoop(10000, function() {
health=health-0.1;
updatecounters();
console.log(health);
});
Health 最初设置为 83.3,console.log 打印出以下语句:
83.2
83.10000000000001
83.00000000000001
82.90000000000002
82.80000000000003
82.70000000000003
82.60000000000004
82.50000000000004
82.40000000000005
它应该每 10 秒减少 0.1,但似乎存在浮点错误。我知道我可以通过简单地将变量四舍五入到小数点后两位来解决这个问题,但为什么会这样?
我认为这只是糟糕的编译。如果一个数字有一个终止小数点(少于 32 位)或者是有理数,程序应该能够存储准确的值而不是让像这样的恶作剧发生。我完全理解为什么乘法和除法会导致浮点错误,但是加法和减法不应该导致这样的错误。
可以在减法后的数上调用.toFixed
let health = 83.3;
setInterval(function() {
health = (health - 0.1).toFixed(1);
console.log(health);
}, 500);
但是,.toFixed
会将数字转换为字符串,如果需要将其保留为数字,可以用数字构造函数包装代码:
Number((health - 0.1).toFixed(1));
问题不在于 javascript,但它适用于所有浮点计算,因为 0.1、0.2 和 0.3 不能完全表示。
Check this link了解更多
浮点问题只是生活的一部分。你需要学会和他们一起生活。
你可以试试:
// health (String) is for display, can be values from 100.0 to 0.1
var health = "100.0";
// healthMath (Int) is for calculations. It is an int, not a float.
var healthMath = 1000;
因此,在您的示例中:
timedLoop(10000, function() {
healthMath -= 1;
health = (healthMath / 10).toFixed(1);
updatecounters();
console.log(health);
});