为什么此函数会增加错误的十进制值

Why this function increase wrong decimal values?

本文关键字:十进制 错误 增加 函数 为什么      更新时间:2023-09-26

可能重复:
JavaScript的浮点数学坏了吗
在JavaScript 中舍入浮点值

为什么这个函数会增加错误的十进制值?我只想显示一个小数。

var valueElement = $('#valueTempe');
function incrementValue(e){
    if(valueElement.text() < 6){
        valueElement.text(Math.max(parseFloat(valueElement.text()) + e.data.increment)); 
    }
    return false;
}
$('#plus').bind('click', {increment: 0.1}, incrementValue);     
$('#minus').bind('click', {increment: -0.1}, incrementValue);

jsFiddle:测试

同样,1/3不能用十进制精确表示,0.1不能用二进制精确表示,Javascript数字是二进制浮点值。

在Javascript中,0.2 + 0.1返回0.30000000000000004
请在浏览器控制台中尝试。

实际上,53位可用于存储Javascript 64位浮点值中的尾数,二进制四舍五入到53位精度的十进制值0.1
0.00011001100110011001100110011001100110011001100110011010
当转换回十进制时正是
0.1000000000000000055511151231257827021181583404541015625

我们可以在Firefox中使用toFixed来显示这一点(其他浏览器将参数限制为20(:
(0.1).toFixed(55)返回CCD_ 10。

同样,二进制四舍五入到53位精度,然后转换回十进制的十进制值0.2正是
0.200000000000000011102230246251565404236316680908203125

如果我们把0.10.2的两个二进制表示相加,四舍五入到53位,然后转换回十进制,我们就得到了
0.3000000000000000444089209850062616169452667236328125

因此,Javascript中0.1+0.2的结果不是0.3,而是小数点后17位的0.30000000000000004

事实上,0.3无论如何都不能用二进制本身来精确表示
它实际上存储为十进制值的二进制等价物
0.29999999999999993338661852249060757458209991455078125
这就是为什么在Javascript中
CCD_ 22返回CCD_。


十进制到二进制
如果2是十进制数分母的唯一质因子,则十进制数只能用二进制精确表示
例如,
0.11/10,而10有素因子25,因此没有精确的表示
0.51/2,而2的唯一素因子是2,所以它可以被精确地表示。

您可以使用.toFixed(1(,如下

var valueElement = $('#valueTempe');
function incrementValue(e){
    if(valueElement.text() < 6){
        valueElement.text(Math.max(parseFloat(valueElement.text()) + e.data.increment).toFixed(1)); 
    }
    if(valueElement.text() == 6){
        valueElement.text(Math.max(parseFloat(valueElement.text()) -1).toFixed(1));
    }
    return false;
}

$('#plus').bind('click', {increment: 0.1}, incrementValue);     
$('#minus').bind('click', {increment: -0.1}, incrementValue);

演示