Javascript浮点数运算及比较代码收集整理

以下代码转自:http://segmentfault.com/a/1190000000324193

浮点数加法:

/**
 ** 加法函数,用来得到精确的加法结果
 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
 ** 调用:accAdd(arg1,arg2)
 ** 返回值:arg1加上arg2的精确结果
 **/
function accAdd(arg1, arg2) {    
    var r1, r2, m, c;    
    try {
        r1 = arg1.toString().split(".")[1].length;
    } catch (e) {
        r1 = 0;
    }    
    try {
        r2 = arg2.toString().split(".")[1].length;
    } catch (e) {
        r2 = 0;
    }
    c = Math.abs(r1 - r2);
    m = Math.pow(10, Math.max(r1, r2));    
    if (c > 0) {        
        var cm = Math.pow(10, c);        
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace(".", ""));
            arg2 = Number(arg2.toString().replace(".", "")) * cm;
        } else {
            arg1 = Number(arg1.toString().replace(".", "")) * cm;
            arg2 = Number(arg2.toString().replace(".", ""));
        }
    } else {
        arg1 = Number(arg1.toString().replace(".", ""));
        arg2 = Number(arg2.toString().replace(".", ""));
    }    
    return (arg1 + arg2) / m;
}

//给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg) {    
    return accAdd(arg, this);
};

浮点数减法:

/**
 ** 减法函数,用来得到精确的减法结果
 ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
 ** 调用:accSub(arg1,arg2)
 ** 返回值:arg1加上arg2的精确结果
 **/
function accSub(arg1, arg2) {
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

// 给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.sub = function (arg) {
    return accMul(arg, this);
};

浮点数乘法:

/**
 ** 乘法函数,用来得到精确的乘法结果
 ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
 ** 调用:accMul(arg1,arg2)
 ** 返回值:arg1乘以 arg2的精确结果
 **/
function accMul(arg1, arg2) {
    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length;
    }
    catch (e) {
    }
    try {
        m += s2.split(".")[1].length;
    }
    catch (e) {
    }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}

// 给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.mul = function (arg) {
    return accMul(arg, this);
};

浮点数除法:

/** 
 ** 除法函数,用来得到精确的除法结果
 ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
 ** 调用:accDiv(arg1,arg2)
 ** 返回值:arg1除以arg2的精确结果
 **/
function accDiv(arg1, arg2) {
    var t1 = 0, t2 = 0, r1, r2;
    try {
        t1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
    }
    try {
        t2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
    }
    with (Math) {
        r1 = Number(arg1.toString().replace(".", ""));
        r2 = Number(arg2.toString().replace(".", ""));
        return (r1 / r2) * pow(10, t2 - t1);
    }
}

//给Number类型增加一个div方法,调用起来更加方便。
Number.prototype.div = function (arg) {
    return accDiv(this, arg);
};

以下内容来自于:http://madscript.com/javascript/javscript-float-number-compute-problem/

分析

JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的。 浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的:

十进制           二进制
0.1              0.0001 1001 1001 1001 ...
0.2              0.0011 0011 0011 0011 ...
0.3              0.0100 1100 1100 1100 ...
0.4              0.0110 0110 0110 0110 ...
0.5              0.1
0.6              0.1001 1001 1001 1001 ...

所以比如 1.1 ,其程序实际上无法真正的表示 ‘1.1’,而只能做到一定程度上的准确,这是无法避免的精度丢失:

1.09999999999999999

在JavaScript中问题还要复杂些,这里只给一些在Chrome中测试数据:

输入               输出
1.0-0.9 == 0.1     False
1.0-0.8 == 0.2     False
1.0-0.7 == 0.3     False
1.0-0.6 == 0.4     True
1.0-0.5 == 0.5     True
1.0-0.4 == 0.6     True
1.0-0.3 == 0.7     True
1.0-0.2 == 0.8     True
1.0-0.1 == 0.9     True

目前比较流行的方法:在判断浮点运算结果前对计算结果进行精度缩小,因为在精度缩小的过程总会自动四舍五入

(1.0-0.9).toFixed(digits)                      // toFixed() 精度参数须在 0 与20 之间
parseFloat((1.0-0.9).toFixed(10)) === 0.1      // 结果为True
parseFloat((1.0-0.8).toFixed(10)) === 0.2      // 结果为True
parseFloat((1.0-0.7).toFixed(10)) === 0.3      // 结果为True
parseFloat((11.0-11.8).toFixed(10)) === -0.8   // 结果为True

对以上思路经行封装

// 通过isEqual工具方法判断数值是否相等
function isEqual(number1, number2, digits){
    digits = digits == undefined? 10: digits; // 默认精度为10
    return number1.toFixed(digits) === number2.toFixed(digits);
}

isEqual(1.0-0.7, 0.3);  // return true

// 原生扩展方式,更喜欢面向对象的风格
Number.prototype.isEqual = function(number, digits){
    digits = digits == undefined? 10: digits; // 默认精度为10
    return this.toFixed(digits) === number.toFixed(digits);
}

(1.0-0.7).isEqual(0.3); // return true
时间: 2024-10-05 06:50:15

Javascript浮点数运算及比较代码收集整理的相关文章

【转】javascript 浮点数运算问题

大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子 alert(45.6*13); 结果居然是592.800000000001,当然加法之类的也会有这个问题 那这是js的错误吗? 当然不是,你的电脑做着正确的二进制浮点运算,但问题是你输入的是十进制的数,电脑以二进制运算,这两者并不是总是转化那么好的,有时候会得到正确的结果,但有时候就不那么幸运了 alert(0.7+0.1);//输出0.7999999999999999 alert(0.6+0.2);//输出0

响应式网站代码收集整理

1.meta标签 大多数移动浏览器将HTML页面放大为宽的视图(viewport)以符合屏幕分辨率.你可以使用视图的meta标签来进行重置.下面的视图标签告诉浏览器,使用设备的宽度作为视图宽度并禁止初始的缩放.在标签里加入这个meta标签 <   meta name="viewport" content="width=device-width, initial-scale=1.0"   > IE8或者更早的浏览器并不支持Media Query.你可以使用

JavaScript 浮点数运算 精度问题

JavaScript小数在做四则运算时,精度会丢失,这会在项目中引起诸多不便,先请看下面脚本. 1 //加减 2 <script type="text/javascript" language="javascript"> 3 alert(1/3);//弹出: 0.3333333333333333 4 alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 5 alert(-0.09999999 -

javascript浮点数运算修正

众所周知,javascript对于浮点数的运算一直都是有问题的,比如0.2+0.1 结果是 0.30000000000000004. 下面是我的解决方案,先贴代码了: var calMath = (function() { var isFloat = function(a) { var reg = /\d.\d+/g return reg.test(a) } var getFloatDigit = function(a) { var digit, len a = a.toString() dig

【javascript】浮点数运算问题分析及解决方法

问题: 在用 js 进行小数四则运算时发现了一个重大问题,比如:0.7 * 0.8 = 0.5599999999999999 分析: 在 js 中只有一种数字类型 Number,而且在 js 中所有的数字都是以 IEEE-754 标准格式表示的.浮点数的精度问题并不是 js 特有的,因为有些小数以二进制表示位数是无穷的,比如 1.1,其程序实际上无法真正的表示 1.1,而只能做到一定程度上的准确(1.09999999999999999),这是无法避免的精度丢失. 通过 chrome 控制台,我们

JavaScript 浮点数及运算精度调整总结

JavaScript 浮点数及运算精度调整总结 JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的. 作者:来源:theWalker|2015-12-02 10:21 移动端 收藏 分享 [技术沙龙]AI开发者实战营-7分钟打造1个定制技能.7月22号,我们等你一起! JavaScript 只有一种数字类型 Number,而且在Jav

Java代码报错[收集整理]

1. com.ibatis.common.jdbc.exception.NestedSQLException: com.ibatis.common.jdbc.exception.NestedSQLException: --- The error occurred in com/visec/fileIssue/domain/fileIssue.xml. --- The error occurred while applying a parameter map. --- Check the file

最常用的PHP正则表达式收集整理

最常用的PHP正则表达式收集整理 提交 我的评论 加载中 已评论 最常用的PHP正则表达式收集整理 2015-03-20 PHP100中文网 PHP100中文网 PHP100中文网 微信号 功能介绍 互联网开发者社区,提供相关技术信息服务,技术交流着平台 正则表达式用于字符串处理.表单验证等场合,实用高效.本文收集了一些常用的表达式: view sourceprint? $str = preg_replace("/(<a.*?>)(.*?)(<\/a>)/",

工作流,WEB框架,UI组件网络收集整理

工作流,WEB框架,UI组件网络收集整理 在博客园上逛了好多年,随手收录了一些工作流,WEB开发框架,UI组件,现在整理一下与大家分享. 由于个人能力与精力有限,望各位园友在评论中补充,我将全部整理到正文: ? 工作流篇 RoadFlow工作流(收费):                  http://www.cqroad.cn/WorkFlow 驰骋工作流引擎 ccflow                       https://www.oschina.net/p/ccflow YbSof