js浮点数精度问题
大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子
alert(45.6*13);
结果居然是592.800000000001,当然加法之类的也会有这个问题
那这是js的错误吗?
当然不是,你的电脑做着正确的二进制浮点运算,但问题是你输入的是十进制的数,电脑以二进制运算,这两者并不是总是转化那么好的,有时候会得到正确的结果,但有时候就不那么幸运了
alert(0.7+0.1);//输出0.7999999999999999
alert(0.6+0.2);//输出0.8
你输入两个十进制数,转化为二进制运算过后再转化回来,在转化过程中自然会有损失了
但一般的损失往往在乘除运算中比较多,而JS在简单的加减法里也会出现这类问题,你也看到了,这个误差也是非常小的,但是却是不该出现的
那该怎么解决呢,ECMA4似乎给了解决方法,但是现在倒不是那么实用的
一种方法,比如0.7+0.1,先把0.1和0.7都乘10,加完之后再除10
另外可以自己写点函数来解决这个问题,自己百度谷歌一下应该有很多,但是最好还是不要用JS做一些复杂的浮点运算,毕竟JS更多的作用不在于此
<script type="text/javascript"> // 两个浮点数求和
function accAdd(num1,num2){
var r1,r2,m;
try{
r1 = num1.toString().split('.')[1].length;
}catch(e){
r1 = 0;
}
try{
r2=num2.toString().split(".")[1].length;
}catch(e){
r2=0;
}
m=Math.pow(10,Math.max(r1,r2));
// return (num1*m+num2*m)/m;
return Math.round(num1*m+num2*m)/m;
} // 两个浮点数相减
function accSub(num1,num2){
var r1,r2,m;
try{
r1 = num1.toString().split('.')[1].length;
}catch(e){
r1 = 0;
}
try{
r2=num2.toString().split(".")[1].length;
}catch(e){
r2=0;
}
m=Math.pow(10,Math.max(r1,r2));
n=(r1>=r2)?r1:r2;
return (Math.round(num1*m-num2*m)/m).toFixed(n);
}
// 两数相除
function accDiv(num1,num2){
var t1,t2,r1,r2;
try{
t1 = num1.toString().split('.')[1].length;
}catch(e){
t1 = 0;
}
try{
t2=num2.toString().split(".")[1].length;
}catch(e){
t2=0;
}
r1=Number(num1.toString().replace(".",""));
r2=Number(num2.toString().replace(".",""));
return (r1/r2)*Math.pow(10,t2-t1);
} function accMul(num1,num2){
var m=0,s1=num1.toString(),s2=num2.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);
} </script> <script>
document.write("使用js原生态方法");
document.write("<br/> 1.01 + 1.02 ="+(1.01 + 1.02));
document.write("<br/> 1.01 - 1.02 ="+(1.01 - 1.02));
document.write("<br/> 0.000001 / 0.0001 ="+(0.000001 / 0.0001));
document.write("<br/> 0.012345 * 0.000001 ="+(0.012345 * 0.000001));
document.write("<br/><hr/>");
document.write("<br/>使用自定义方法");
document.write("<br/> 1.01 + 1.02 ="+accAdd(1.01,1.02));
document.write("<br/> 1.01 - 1.02 ="+accSub(1.01,1.02));
document.write("<br/> 0.000001 / 0.0001 ="+accDiv(0.000001,0.0001));
document.write("<br/> 0.012345 * 0.000001 ="+accMul(0.012345,0.000001));
</script>
js浮点数精度问题的更多相关文章
- js浮点数精度丢失问题及如何解决js中浮点数计算不精准
js中进行数字计算时候,会出现精度误差的问题.先来看一个实例: console.log(0.1+0.2===0.3);//false console.log(0.1+0.1===0.2);//true ...
- js精确计算(js浮点数精度问题)
转自:http://talentluke.iteye.com/blog/1767138 大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子 alert(45.6*13 ...
- JS浮点数精度运算
一般来讲,我们在项目中必不可少的需要进行各种数值的计算,但是这种计算全部放在服务端会给服务器带来很大的压力,所以势必要客户端来 分担一些计算的压力. 从客户端来说,JavaScript是一门弱类型语言 ...
- 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS浮点数计算精度问题
本文讲解的是怎么实现一个工具库并打包发布到npm给大家使用.本文实现的工具是一个分数计算器,大家考虑如下情况: \[ \sqrt{(((\frac{1}{3}+3.5)*\frac{2}{9}-\fr ...
- 关于js浮点数计算精度不准确问题的解决办法
今天在计算商品价格的时候再次遇到js浮点数计算出现误差的问题,以前就一直碰到这个问题,都是简单的使用tofixed方法进行处理一下,这对于一个程序员来说是及其不严谨的.因此在网上收集了一些处理浮点数精 ...
- js浮点数计算问题 + 金额大写转换
一 js浮点数计算问题解决方案: 1.使用 NumberObject.toFixed(num) 方法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 2.较精度计算浮点数 ...
- js中精度问题以及解决方案
js中的数字按照IEEE 754的标准,使用64位双精度浮点型来表示.其中符号位S,指数位E,尾数位M分别占了1,11,52位,并且在ES5规范中指出了指数位E的取值范围是[-1074, 971]. ...
- js浮点数乘除法
JS在处理浮点数计算时经常会遇到精度的问题,上一篇博客封装了JS浮点数加减法的方法,这一次来封装一下js浮点数乘除法运算. 其实浮点除法的封装跟加减法的封装原理是一样,只是在第一次计算完后会再复位小数 ...
- WebGL着色器32位浮点数精度损失问题
问题 WebGL浮点数精度最大的问题是就是因为js是64位精度的,js往着色器里面穿的时候只能是32位浮点数,有效数是8位,精度丢失比较严重. 这篇文章里讲了一些处理方式,但是视坐标这种方式放在我们的 ...
随机推荐
- 动画原理——脉动(膨胀缩小)&&无规则运动
书籍名称:HTML5-Animation-with-JavaScript 书籍源码:https://github.com/lamberta/html5-animation 1.脉动是一种半径r来回反复 ...
- c#导出文件,文件名中文乱码解决方法。
public string clFielName(string fileName) { System.Web.HttpContext curContext = System.Web.HttpConte ...
- java 线程之间通信以及notify与notifyAll区别。
jvm多个线程间的通信是通过 线程的锁.条件语句.以及wait().notify()/notifyAll组成. 下面来实现一个启用多个线程来循环的输出两个不同的语句. package com.app. ...
- Swift 控制流
Swift 1,顺序结构 2,分支结构 switch 中每一个case块完成后会自动终止switch语句, 不用手动终止 case 可有多值,如 case "A","a& ...
- 安装虚拟机VMWare时出现1021错误的解决办法
今天安装虚拟机(VMWare Workstation9.0),中途老是出现错误:Failed to create the requested registry key key installer er ...
- centos之jdk安装
1.环境说明 系统:centos6.7, 2.6.32-573.el6.x86_64; jdk:jdk1.7.0_80 2.下载jdk并上传 下载jdk-7u80-linux-x64.tar ...
- The Best Coder and Why? (最牛气的程序员)——精彩!
原文出处我已经找不到了,总之不是原创了,不过,重新看过,挺受震撼的.程序员出身的我们,或许记不住某些算法细节,但记住他们的名字,也许是应该的. MIT BBS上说微软电话面试的一道题就是“Who do ...
- iOS 4.2 SDK安装
iOS 4.2 SDK安装 ◆系统版本:10.6.5 ◆硬件配置: ◆10G空间,3.5G内存,显卡:GMA950 Xcode 3.2.5和iOS 4.2 SDK下载:http://developer ...
- poj2538---字符匹配(映射)
#include <stdio.h> #include <stdlib.h> #include<string.h> int main() { int i,j; ], ...
- Dyanmics CRM您无法登陆系统。原因可能是您的用户记录或所属的业务部门在Microoft Dynamics CRM中已被禁用
当在操作CRM时,做不论什么的写操作包含创建数据.更新数据.都会提示以下截图中的错误:"您无法登陆系统.原因可能是您的用户记录或所属的业务部门在Microoft Dynamics CRM中已 ...