`

JavaScript浮点数运算 —— 精度问题

阅读更多

JavaScript小数在做四则运算时,精度会丢失,这会在项目中引起诸多不便,先请看下面脚本:

<script type="text/javascript" language="javascript">   
	alert(1/3);//弹出: 0.3333333333333333
	alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 
	alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999
	alert(0.012345 * 0.000001);//弹出: 1.2344999999999999e-8
	alert(0.000001 / 0.0001);//弹出: 0.009999999999999998
</script>  

   按正常计算的话,除第一行外(因为其本身就不能除尽),其他都应该要得到精确的结果,从弹出的结果我们却发现不是我们想要的正确结果。为了解决浮点数运算不准确的问题,在运算前我们把参加运算的数先升级(10的X的次方)到整数,等运算完后再降级(0.1的X的次方)。现收集并整理贴于此,以备后用。

 

 

//加法
Number.prototype.add = function(arg){
    var r1,r2,m;
    try{r1=this.toString().split(".")[1].length}catch(e){r1=0}
    try{r2=arg.toString().split(".")[1].length}catch(e){r2=0}
    m=Math.pow(10,Math.max(r1,r2))
    return (this*m+arg*m)/m
}

//减法
Number.prototype.sub = function (arg){
    return this.add(-arg);
}

//乘法
Number.prototype.mul = function (arg)
{
    var m=0,s1=this.toString(),s2=arg.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.prototype.div = function (arg){
    var t1=0,t2=0,r1,r2;
    try{t1=this.toString().split(".")[1].length}catch(e){}
    try{t2=arg.toString().split(".")[1].length}catch(e){}
    with(Math){
        r1=Number(this.toString().replace(".",""))
        r2=Number(arg.toString().replace(".",""))
        return (r1/r2)*pow(10,t2-t1);
    }
}

 

测试一把

<script type="text/javascript" language="javascript">

	/*
	 alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999
	 alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999
	 alert(0.012345 * 0.000001);//弹出: 1.2344999999999999e-8
	 alert(0.000001 / 0.0001);//弹出: 0.009999999999999998
	*/
	 alert(Number(0.09999999).add(0.00000001));//弹出: 0.1
 	//注意,如果是负数,一定要先使用Number转型,否则结果不正确
	alert(Number(-0.09999999).sub(0.00000001));//弹出: -0.1
 	alert(Number(0.012345).mul(0.000001));//弹出: 1.2345e-8
 	alert(Number(0.000001).div(0.0001));//弹出: 0.01

</script>

 

分享到:
评论
8 楼 虾米小尹 2018-10-25  
不行啊!2.2-0.25=1.9500000000000002
7 楼 littlehehe 2014-06-14  

感谢你的博客文章,帮我解决了问题!
我在做GIS,测试没有问题。
6 楼 chanyizheng23 2013-07-17  
359468787 写道
-35 + 1.66 + 1.77 你测试一下(数字的顺序别弄反了)


你直接说:
-33.34 + 1.77 有问题吧
因为 -33.34 * 100 有问题
5 楼 can_teen 2012-04-10  
当小数位很多时,用toString获得的字符串是科学计数法的形式,这时,用split('.')就无法正确获得小数位
4 楼 junJZ_2008 2010-12-13  
359468787 写道
这几天又测试了一下,发现
53808.9592  div  1 = 53808.959200000005
4292.3478   div  1 = 4292.3478000000005
还真是有点郁闷了!

很正常,这是由于不能正确表示53808.9592浮点数所致,Java浮点也有这样的问题,可使用Big数据类型解决,JavaScript就不知道有什么好的办法没有
3 楼 junJZ_2008 2010-12-13  
359468787 写道
-35 + 1.66 + 1.77 你测试一下(数字的顺序别弄反了)
alert(Number(-35).add(1.66).add(1.77));//弹出:-31.570000000000004

2 楼 359468787 2010-09-30  
这几天又测试了一下,发现
53808.9592  div  1 = 53808.959200000005
4292.3478   div  1 = 4292.3478000000005
还真是有点郁闷了!
1 楼 359468787 2010-09-26  
-35 + 1.66 + 1.77 你测试一下(数字的顺序别弄反了)

相关推荐

    js算法精度失真问题的解决方案

    ### js算法精度失真问题的解决...通过这些函数,可以在很大程度上避免由于浮点数运算导致的精度问题,特别是在需要高精度计算的应用场景中尤为重要。开发者可以根据实际需求选择合适的方法来确保应用的稳定性和准确性。

    javascript解决小数的加减乘除精度丢失的方案.docx

    在JavaScript中处理小数运算时,经常会遇到一个令人头疼的问题——精度丢失。这主要是因为JavaScript中的数字采用IEEE 754标准下的双精度64位浮点数格式表示,而这种表示方法对于某些特定的十进制小数无法做到精确...

    JavaScript权威指南第6版

    - **数值类型**:介绍了数值的基本操作和常见陷阱,例如整数溢出和浮点数的精度问题。 - **字符串类型**:讲解了字符串的拼接、分割、替换等操作,以及正则表达式的使用。 - **布尔类型**:解释了布尔值的逻辑...

    MathTask_单元测试_加减乘除运算_

    3. **精度测试**:对于浮点数运算,需要考虑精度问题,例如近似值的比较、舍入误差等。 4. **性能测试**:虽然这不是单元测试的主要目标,但对大量数据的运算速度进行测试,可以评估算法的效率。 5. **组合测试**...

    very-simple-statistics-adapter:线性任意精度的非常简单的统计适配器

    此外,"very-simple-statistics-adapter"强调了“线性任意精度”,这意味着它可以处理大数值或者需要高精度计算的情况,不会因为浮点数运算的精度问题导致结果误差。这对于处理大规模数据或需要精确统计分析的场景...

    前端项目-crunch.zip

    Crunch库支持这种运算,这对于处理金融计算中的除法问题非常有用,可以避免浮点数运算带来的精度损失。 3. **其他算术运算**:除了上述高级功能,Crunch还提供了基本的加、减、乘、除等算术操作,且这些操作同样...

    javascript 全

    5. **BigInt**:ES10引入的新类型,用于处理大整数,避免了Number类型的精度问题。 6. **String**:字符串由零个或多个字符组成,用单引号或双引号括起来。 7. **Symbol**:每个Symbol值都是唯一的,常用于对象属性...

    javascript从入门到跑路—–小文的js学习笔记(3)———javascript中的数据类型

    8. **BigInt**:用于表示任意大小的整数,解决了 JavaScript 在处理大整数时的精度问题。例如: ```javascript var bigInt = 9007199254740991n; ``` 理解这些数据类型对于编写有效的JavaScript代码至关重要,...

    前端开源库-max-safe-integer

    "max-safe-integer" 这个开源库是针对JavaScript中的一个关键特性——最大安全整数(Max Safe Integer)而设计的。这个库提供了一个 ponyfill(部分实现),旨在帮助开发者在不支持ES2015新特性的环境中使用 Number....

    JS——Number

    在实际编程中,尤其要注意`NaN`的特性,以及数值精度问题,因为JavaScript在处理大于`Number.MAX_SAFE_INTEGER`的整数时可能会出现不准确的情况。了解并掌握这些知识点,对于提升JavaScript编程技能至关重要。

    浅谈javascript六种数据类型以及特殊注意点

    - JavaScript中的浮点数运算可能存在精度问题,如`0.1 + 0.2 !== 0.3`。 - 支持科学计数法运算,例如`1e3`代表1000。 - NaN(Not a Number)表示非数字值,`0/0`会产生NaN。 - 使用`isNaN()`检测是否为NaN,但...

    前端面试题之baseJS-number.zip

    2. **精度问题** JavaScript的Number类型以IEEE 754双精度浮点数格式存储数值,因此在进行大整数运算时可能会遇到精度损失。例如,两个看似相等的数字在JavaScript中可能不完全相等,这通常需要使用`Number.EPSILON...

    js代码-Number.MIN_SAFE_INTEGER

    这个数值在JavaScript的数字运算中扮演着重要的角色,因为JavaScript使用了双精度浮点数格式(IEEE 754)来存储数字,这导致在处理非常大或非常小的整数时可能会出现精度问题。 在深入理解`Number.MIN_SAFE_INTEGER...

    JavaScript 学习初步 入门教程

    在JavaScript中,浮点型只有一种精度,即双精度,这意味着所有浮点数都会以64位双精度格式存储。声明变量时,只需要使用`var`关键字,无需像其他语言(如C#)那样区分`int`, `long`, `float`, `double`等。变量的...

    计算器运算加减乘除法德运算啊哈哈

    对于浮点数,需要考虑精度问题,避免因舍入误差导致的结果不准确。 5. 清零与清除:计算器通常提供清零和清除功能,以便用户进行新的计算。清零仅清除当前显示的数字,清除则重置所有输入和结果。 在编程实现中,...

    前端面试资料,适合中高级前端面试者

    需要注意的是,浮点数在进行运算时可能会出现精度问题。 - `string`: 字符串类型,用于存储文本数据。 - `symbol`: ES6引入的新类型,用于创建唯一标识符。 - **对象类型** (`Object`):这是一种引用类型,可以...

    苹果iPhone手机在线计算器

    为了确保精度,计算器可能会使用浮点数运算,因为普通的整数运算可能会在处理小数时丢失精度。在JavaScript中,这涉及到Number对象和它的方法,如toFixed()用于格式化数字到指定的小数位数。 此外,计算器可能还...

    JS 数据类型转换

    **BigInt**:从ES2020开始,JavaScript引入了BigInt类型来处理大整数,避免了Number类型在处理大整数时的精度问题。 **String**:字符串是由一串字符组成的,它们是不可变的。可以使用单引号或双引号创建字符串,...

    EndlessNumbers

    本文将深入探讨JavaScript中的数字类型、精度问题以及如何有效地处理无限序列。 1. **JavaScript 数字类型** JavaScript只有一个内置的数字类型——`Number`。这个类型可以表示整数和浮点数,但有一个限制:它使用...

Global site tag (gtag.js) - Google Analytics