javascript - 为什么这个函数会增加错误的小数值?

标签 javascript

Possible Duplicate:
Is JavaScript’s Floating-Point Math Broken?
Rounding a float in 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:Test

最佳答案

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

在 JavaScript 中 0.2 + 0.1返回0.30000000000000004 .
在浏览器控制台中尝试一下。

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

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

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

如果我们将 0.1 的两个二进制表示相加和0.2 ,四舍五入到 53 位,然后转换回十进制,我们得到准确的
0.3000000000000000444089209850062616169452667236328125 .

所以结果是0.1 + 0.2在 Javascript 中不是 0.3但是,精确到小数点后 17 位,是 0.30000000000000004 .

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


十进制转二进制
十进制数只能用二进制精确表示,如果 2当该数以最低形式表示为简单分数时,是该数分母的唯一质因数。
例如,
0.11/10 ,和10有质因数25 ,所以没有确切的表示。
0.51/2 ,以及 2 的唯一素因数是 2因此可以准确地表示。

关于javascript - 为什么这个函数会增加错误的小数值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14398337/

相关文章:

JavaScript 文件路径问题/错误

javascript - 用户交互倒计时增加

javascript - React-native UI 挑战

javascript - 为什么我的 3em div 比我的 3em 渐变图案小?

javascript - Heroku Node.js 应用程序与 buildpack 不兼容

javascript - 通过循环将 CSS 类应用于每个 <li> 元素

javascript - 从上传的 csv 数据创建数据表列定义

Javascript - 如何快速构造不同正整数数组的二进制表示

javascript - 在顶部创建一个 div 将所有其他内容向下推

javascript - 日期类转换时间戳错误