`
123003473
  • 浏览: 1060310 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

javascript中的float运算精度

 
阅读更多
有人问到一个js问题:

view plainprint?

    var i = 0.07; 
    var r = i*100; 
    alert(r); 

结果为什么是7.0000000000000001?

查了下资料,其实我们知道JavsScript中,变量在存储时并不区分number和float类型,而是统一按float存储。而javascript使用IEEE 754-2008 标准定义的64bit浮点格式存储number,按照IEEE 754的定义: http://en.wikipedia.org/wiki/IEEE_754-2008

decimal64对应的整形部分长度为10, 小数部分长度为16,所以默认的计算结果为“7.0000000000000001”,如最后一个小数为0,则取1作为有效数字标志。

类似地,我们可以想像,1/3的结果应该是0.3333333333333333。

那么如何校正这个值呢?

可以用以下方法:
一、parseInt

var r4=parseInt(i*100);

二、Math.round

var r2=Math.round((i*100)*1000)/1000;




<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>
<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的次方)。现收集并整理贴于此,以备后用。
加法
Js代码
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1,arg2){
var r1,r2,m;
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))
return (arg1*m+arg2*m)/m
}
//给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
function accAdd(arg1,arg2){
var r1,r2,m;
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))
return (arg1*m+arg2*m)/m
}
//给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg){
return accAdd(arg,this);
}
减法

//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
//调用:accSub(arg1,arg2)
//返回值:arg1减上arg2的精确结果
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
//给Number类型增加一个sub方法,调用起来更加方便。
Number.prototype.sub = function (arg){
return accSub(this,arg);
}
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
//调用:accSub(arg1,arg2)
//返回值:arg1减上arg2的精确结果
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
//给Number类型增加一个sub方法,调用起来更加方便。
Number.prototype.sub = function (arg){
return accSub(this,arg);
} 



//说明: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的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用: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);
} 除法
Js代码
//说明: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);
}
//说明: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);
} 

  


  
分享到:
评论
1 楼 Leonhard7 2012-03-01  
老实说这些方法根本不行。想想本来就是浮点数运算有问题,方法里面充斥着对浮点数的运算,所以根本行不通。

相关推荐

    javascript中的float运算精度实例分析

    在JavaScript编程中,浮点数的运算精度是一个需要特别注意的问题。在处理金融数据、科学计算或任何需要精确数值的场景下,精度问题尤为突出。JavaScript中的number类型是基于IEEE 754标准的双精度浮点数表示,意味着...

    使用Vue.js及Element编写的精度浮点运算计算器源码(打开运行)

    由于javascript的浮点运算是不精确的(对于大多数编程语言都是这样),此程序使用整数来代替浮点数进行运算,最后再转化为浮点数,可以实现对设置范围内(运算范围在程序中为自定义变量range)的浮点运算实现精度...

    main_half_javascript_半精度浮点数_Uint8Array_

    7. **其他工具和库**:有些JavaScript库如`floaty`或`half-float`已经实现了对半精度浮点数的支持,可以考虑使用这些库来简化开发工作。 综上所述,理解和掌握半精度浮点数以及如何在JavaScript的`Uint8Array`上下...

    js计算精度问题解决方案

    在JavaScript编程语言中,计算精度问题是一个...如果压缩包中的"js-float-accuracy-master"库提供了实用的解决方案,那么它可能包含了一些优化的算法或工具,以帮助开发者更好地处理JavaScript中的浮点数计算精度问题。

    JS浮点数字操作插件floatOPS.js

    在JavaScript编程中,...总结起来,floatOPS.js是一个专注于解决JavaScript中浮点数运算精度问题的插件,通过提供加减乘除四个方法,确保了在进行浮点数运算时的精度,对于需要精确计算的场景具有很高的实用价值。

    前端面试题之baseJS-floatpoint.zip

    本篇文章将深入探讨“前端面试题之baseJS-floatpoint”这一主题,主要聚焦于JavaScript中的浮点数处理及其相关的面试知识点。 首先,我们要明白JavaScript中的数值类型主要分为两种:整数和浮点数。浮点数(Float ...

    详谈javascript精度问题与调整

    在JavaScript中,它不存在传统编程语言中如int、float或double这样的数据类型之分,而是统一使用了number类型来表示数值。这个number类型遵循IEEE754标准的浮点数表示法。因此,JavaScript中的数值运算实际上是按照...

    double.js:javascript中的double-double运算。 具有31个精确十进制数字的浮点扩展

    具有31个准确的十进制数字(106位)的浮点展开,也称为双精度双精度算术或模拟float128。 该库对于扩展精度的快速计算很有用。 例如,在轨道力学,计算几何和数值不稳定算法中,例如执行三角剖分,多边形修剪,求逆...

    JavaScript 获取任一float型小数点后两位的小数

    在JavaScript中,有时我们需要对浮点数(float型)进行操作,特别是获取小数点后特定位数的数值。这通常涉及到精度处理和四舍五入的问题。以下是一些方法来实现这一目标,特别是获取小数点后两位的数字。 1. **基本...

    js为什么不能正确处理小数运算?

    在C语言中,变量sum被声明为float类型,这同样是一个单精度浮点数,其精度比JavaScript中的Number类型还要低。 解决这个问题的方法包括使用库函数进行更精确的小数运算,或者在可能的情况下避免使用浮点数进行精确...

    JavaScript基础练习_day2

    - 为了避免浮点数运算带来的精度问题,可以将浮点数乘以适当的倍数转化为整数再进行运算,或者使用 `toFixed()` 方法对结果进行四舍五入。 2. **解决方法**: - 示例中提供的两种解决方案: - `(0.1 + 0.2)....

    JavaScript解决浮点数计算不准确问题的方法分析

    总的来说,处理JavaScript中的浮点数精度问题,关键在于理解浮点数的二进制表示和存储限制,并采取适当的策略,如转换为整数运算或使用高精度库,以确保计算结果的准确性。在实际开发中,需要根据具体需求选择合适的...

    numjs:JavaScript 中的快速数值操作

    `numjs`通过优化,实现了与NumPy类似的内存布局,可以使用Float32或Float64两种精度的浮点数,以适应不同的计算需求。 此外,`numjs`的API设计遵循了JavaScript的编程习惯,使得开发者可以轻松上手。例如,可以通过...

    fewpjs-js-fundamentals-arithmetic-lab-online-web-ft-110419

    算术实验室学习目标认识JavaScript中数学的局限性聘请运算符执行算术运算并将值赋给变量解释什么是NaN 使用内置对象(如Math和Number来完成复杂的任务介绍我们将讨论许多用于在JavaScript中执行算术运算的常见运算符...

    计算器--简单的加减乘除

    在大多数编程语言中,如JavaScript、Python或Java,浮点数(例如,`float`或`double`类型)是用于表示小数的,但它们并非完全精确。这是因为浮点数在计算机内部是以二进制形式存储的,某些十进制小数无法精确地转换...

    js保留两位小数

    除了上述的`tofloat`函数外,还有多种方法可以在JavaScript中保留指定数量的小数位: 1. **使用`toFixed()`方法**: - `toFixed()`方法可以将数字转换为字符串,并保留指定位数的小数。 - 示例:`console.log((2....

    js-basics-arithmetic-lab-online-web-ft-110419

    JavaScript基础知识:算术实验室 ... 尽管其他语言对于整数,小数等可能具有不同的类型,但是JavaScript将所有内容都表示为双精度浮点数或float 。 这对我们可以使用JavaScript执行的算法的精度施加了一些有趣

    js-basics-arithmetic-lab-v-000

    JavaScript基础知识:算术实验室 ... 虽然其他语言可能具有不同的整数,小数等类型,但JavaScript会将所有内容都表示为双精度浮点数或float 。 这对我们可以使用JavaScript执行的算法的精度施加了一些有趣的技术

Global site tag (gtag.js) - Google Analytics