JS-- 浮点数运算处理
一. 问题描述
最近在做一个项目,页面上会存在一些JS浮点数的运算,发现JS浮点数运算存在一些bug.譬如:
- 0.1+0.2 == 0.30000000000000004
- 0.1 + 0.7 == 0.7999999999999999
- 7*0.8 == 5.6000000000000005
- 5.6/7 == 0.7999999999999999
二.解决方案
JS运算后都会有很小的误差. 不像.Net或者Java那样准确. 主要是JS重点不在运算上面,可是有时候项目一定要用到.想了一下大概有两种解决方案
A 方案一:
运算结果保留2-3位小数位数. 前端界面一般用到的运算比较少。精度要求不会太高。 所以取2位小数位即可。
B. 方案二:
将小数位数转换为整数运算. 譬如:
- 0.1+0.2 =》 (1+2)/10 == 0.3
- 0.1 + 0.7 =》 (1+7)/10 == 0.8
- 7*0.8 == (7*8)/10 == 5.6
- 5.6/7 == (56/7)/10 == 0.1
为了方便调用. 所以我们可以提取一个公共的方法出来.譬如下面的JSMath库,JSMath重写了加减乘除. 会先将参数转换为整数再运算JSMath(参数1).操作(参数2)
参数1和参数2分别就是运算的第一个Number和第二个Number. 计算后通过Value属性获取值.
- (function() {
- var JSMath = function() {
- return this;
- }
- JSMath.prototype.from = function(value) {
- // 支持JSMath参数传递主要是用于嵌套的调用
- if ((typeof(value) == 'object') && (value.value != undefined)) {
- this.value = value.value;
- } else {
- this.value = value;
- }
- return this;
- }
- // 加法
- JSMath.prototype.add = function(value) {
- var thisValueString = this.value.toString();
- var valueString = value.toString();
- var timesCount1 = 0;
- var timesCount2 = 0;
- if (thisValueString.indexOf('.') > 0) {
- timesCount1 = thisValueString.split('.')[1].length;
- }
- if (valueString.indexOf('.') > 0) {
- timesCount2 = valueString.split('.')[1].length;
- }
- var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
- this.value = ((Math.pow(10, maxtimeCount) * this.value + Math.pow(10, maxtimeCount) * value)) / Math.pow(10, maxtimeCount);
- return this;
- }
- // 减法
- JSMath.prototype.sub = function(value) {
- var thisValueString = this.value.toString();
- var valueString = value.toString();
- var timesCount1 = 0;
- var timesCount2 = 0;
- if (thisValueString.indexOf('.') > 0) {
- timesCount1 = thisValueString.split('.')[1].length;
- }
- if (valueString.indexOf('.') > 0) {
- timesCount2 = valueString.split('.')[1].length;
- }
- var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
- this.value = ((Math.pow(10, maxtimeCount) * this.value - Math.pow(10, maxtimeCount) * value)) / Math.pow(10, maxtimeCount);
- return this;
- }
- // 除法
- JSMath.prototype.div = function(value) {
- var thisValueString = this.value.toString();
- var valueString = value.toString();
- var timesCount1 = 0;
- var timesCount2 = 0;
- if (thisValueString.indexOf('.') > 0) {
- timesCount1 = thisValueString.split('.')[1].length;
- }
- if (valueString.indexOf('.') > 0) {
- timesCount2 = valueString.split('.')[1].length;
- }
- var maxtimeCount = timesCount1 > timesCount2 ? timesCount1 : timesCount2;
- this.value = ((Math.pow(10, maxtimeCount) * this.value) / (Math.pow(10, maxtimeCount) * value));
- return this;
- }
- // 乘法
- JSMath.prototype.times = function(value) {
- var thisValueString = this.value.toString();
- var valueString = value.toString();
- var timesCount1 = 0;
- var timesCount2 = 0;
- if (thisValueString.indexOf('.') > 0) {
- timesCount1 = thisValueString.split('.')[1].length;
- }
- if (valueString.indexOf('.') > 0) {
- timesCount2 = valueString.split('.')[1].length;
- }
- var maxtimeCount = timesCount1 + timesCount2;
- this.value = (Math.pow(10, maxtimeCount) * this.value * Math.pow(10, maxtimeCount) * value) / Math.pow(10, maxtimeCount * 2);
- return this;
- }
- if (window.JSMath == undefined) {
- window.JSMath = function(value) {
- var result = new JSMath();
- result.from(value);
- return result;
- }
- }
- })()
B1.基本运算
- 0.1+0.2
- => JSMath(0.1).add(0.2).value == 0.3
- 7+0.8
- => JSMath(7).times(0.8).value == 5.6
- 5.6/7
- => JSMath(5.6).div(7).value = 0.8
B2.多目运算
- 0.05 + 0.05 + 0.2
- => JSMath(JSMath(0.05).add(0.05)).add(0.2).value == 0.3
- (5+0.6)/7
- => JSMath(JSMath(5).add(0.6)).div(7).value == 0.8
三.小总结
上面自己自己暂时知道的一些解决方案.不太清楚是否有开源的更可靠的三方库来解决这个问题,如果有的话,希望博友推荐一下。
贴一下Stockoverflow 里面看到的一些解决方案:
http://stackoverflow.com/questions/3556789/javascript-math-error-inexact-floats
JS-- 浮点数运算处理的更多相关文章
- JS浮点数运算Bug
JS浮点数运算Bug的解决办法(转) 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.0849999 ...
- JS浮点数运算BUG破法
JS里,0.3*3 = 0.8999999999999999 破法1:((0.3*10)*3)/10 破法2:(0.3*3).toFixed(2)//保留两位小数 原因:js浮点数用的是IEEE754 ...
- js浮点数运算的坑,多少同学有碰到过?
javascript中的数字都是双精度的浮点数. JavaScript中的整数并不是一个独立的数据类型,而是浮点数的一个子集. 浮点数的坑我们看下面的例子 在浏览器的console 控制台上我们分别进 ...
- js浮点数运算需要注意的问题
最近在js运算浮点数时发现了一个问题.问题是这样的:js函数中处理两个浮点数的相加,为了防止出现0.1+0.2=0.30000000000000004的问题,两个数都先乘以10000后再相加,得到结果 ...
- js浮点数运算封装, 起因财务部分精确计算
目录 背景 具体代码 背景 项目中用到浮点数,Int 等 js中 Number类型比较多, 加上牵涉到财务软件, 前台js运算等. 有时候会出现精确度的问题 , 公共方法中有好事者写的方法. 此处拿来 ...
- 【转】JS浮点数运算Bug的解决办法
37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一 ...
- JS浮点数运算Bug的解决办法
方法一:重写浮点运算的函数 //除法函数,用来得到精确的除法结果 //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显.这个函数返回较为精确的除法结果. //调用:acc ...
- JS浮点数运算
//乘法函数,用来得到精确的乘法结果 //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显.这个函数返回较为精确的乘法结果. //调用:accMul(arg1,arg2) ...
- js浮点数运算出现误差解决方案
1.数据展示类(使用 toPrecision 凑整并 parseFloat 转成数字后再显示) parseFloat(1.4000000000000001.toPrecision(12)) === 1 ...
- JS 浮点数运算丢失精度解决方案
除法 function accDiv(arg1,arg2){ var t1=0,t2=0,r1,r2; try{t1=arg1.toString().split(".")[1].l ...
随机推荐
- 一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 & 发布
一个技术汪的开源梦 —— 目录 微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 ...
- Core Java 总结(异常类问题)
所有代码均在本地编译运行测试,环境为 Windows7 32位机器 + eclipse Mars.2 Release (4.5.2) 2016-10-17 整理 下面的代码输出结果是多少?为什么?并由 ...
- DG gap sequence修复一例
环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...
- ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考
原文:Razor Syntax Reference 作者:Taylor Mullen.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:何镇汐 什么是 Razor? Razor 是一 ...
- Moon.Orm 配置说明
一.在线技术文档: http://files.cnblogs.com/files/humble/d.pdf 二.使用的大致流程 1.首先下载代码生成器,可以一键生成项目Model层;(其中含有 ...
- CentOS系统MySQL双机热备配置
1 概述 在集成项目中需要应对不同环境下的安装配置,主流操作系统大致可以分为三种:Linux.Windows以及UNIX.其中Linux备受青睐的主要原因有两个: 首先,Linux作为自由软件有两个 ...
- [Q&A] C1DataGrid 奇葩的 BeginNewRow() 方法
一.前言 用户千千万,自然需求就千奇百怪都有,某天有人提了这样一个需求: 某个 C1DataGrid 在 ScrollViewer 的底部(使纵向滚动条显示出来),然后当该 C1DataGrid 增加 ...
- [Winform] DataGridView 中 DataGridViewComboBox 的可编辑
在 DataGridView 中设置的 DataGridViewComboBox,默认是不可编辑的,即使将其列属性 DisplayStyle 设置成 ComboBox 或其他,也无法编辑: 故作如下处 ...
- 【Asp.Net Core】一、Visual Studio 2015 和 .NET Core 安装
安装 Visual Studio 和 .NET Core 1.安装 Visual Studio Community 2015,选择 Community 下载并执行默认安装.Visual Studio ...
- python入门-python解释器执行
最近由于公司需要,接触了python这门神奇的语言,给我的感觉就是开发快速和代码简洁. 开始还是先罗列一下解释性语言和编译性语言的差别吧0.0! 编译性语言:是在程序运行前,需要专门的一个编译过程 ...