css input type 浮点类型_javascript浮点型的一些坑

前言

javascript浮点型运算有很多问题,不管是加减还是乘除,还是四舍五入,都可能出现问题。本文简单介绍一些解决办法,都是工作中总结出来的,有简单,有麻烦。下面就总结一下。

加法运算

例如常见的:

0.1+0.2 //0.30000000000000004

1.4+2.8 //4.199999999999999

等等,这样的好多类似的运算

解决方案一:

简单方法:

这个方法要你知道保留小数点位数,好多情况不是很适用,特殊四舍五入的情况也不准确!

假如保留1位小数

(((0.1+0.2)*10).toFixed(1))/10

保留2位小数

(((0.1+0.2)*100).toFixed(2))/100

解决方案二

精确方法:

定义函数

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

}

accAdd(0.1,0.2)

减法运算

例如:

0.3-0.1 //0.19999999999999998

封装函数方法

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);

}

乘法运算

案例

0.69*10 //6.8999999999999995

11*22.9 //251.89999999999998

解决方案一

如果在知道小数位个数的前提下,可以考虑通过将浮点数放大倍数到整型(最后再除以相应倍数),再进行运算操作,这样就能得到正确的结果了。

例如

0.69*10*10/10

11*(22.9*10)/10

解决方案二

封装函数方法

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)

}

accMul(0.69,10) //6.9

除法运算

例如:

6.9/10 //0.6900000000000001

封装函数方法

function acc(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);

}

}

四舍五入方法

案例如下:

10.145.toFixed(2) ---> "10.14"

四舍五入之后应该是10.15,最后却变成了10.14

原因是因为

10.145.toPrecision(21) ---> "10.1449999999999995737"

解决方案一:

简单解决方案还是先乘以100,然后,四舍五入。最后再除以100

例如

Math.round(10.145*100)/100

当然,也可以用函数封装方法,我们将tofixed重新封装一下:

Number.prototype.toFixed = function (n) {

if (n > 20 || n < 0) {

throw new RangeError('toFixed() digits argument must be between 0 and 20');

}

const number = this;

if (isNaN(number) || number >= Math.pow(10, 21)) {

return number.toString();

}

if (typeof (n) == 'undefined' || n == 0) {

return (Math.round(number)).toString();

}

let result = number.toString();

const arr = result.split('.');

// 整数的情况

if (arr.length < 2) {

result += '.';

for (let i = 0; i < n; i += 1) {

result += '0';

}

return result;

}

const integer = arr[0];

const decimal = arr[1];

if (decimal.length == n) {

return result;

}

if (decimal.length < n) {

for (let i = 0; i < n - decimal.length; i += 1) {

result += '0';

}

return result;

}

result = integer + '.' + decimal.substr(0, n);

const last = decimal.substr(n, 1);

// 四舍五入,转换为整数再处理,避免浮点数精度的损失

if (parseInt(last, 10) >= 5) {

const x = Math.pow(10, n);

result = (Math.round((parseFloat(result) * x)) + 1) / x;

result = result.toFixed(n);

}

return result;

};

小结

处理此类问题,其实都有简单办法,不过,有时候在某种场景下面,简单办法不一定适用罢了。

简单办法一般是:

将浮点数乘以(扩大)10的n次方倍,把浮点数变为整数后再进行相应的运算,最后将得到的结果除以(缩小)10的n次方倍。

但是有时候我们并不知道浮点数的位数,及要精确的小数位数,因此,面对这种场景,我们就要用函数了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值