(1) 在计算机中,数字无论是定点数还是浮点数都是以多位二进制的方式进行存储的。存储一个数值所使用的二进制位数比较多,这样得到的数会更加精确。
(2) 由于存储空间有限,无法整除的小数的时候就会取一个近似值,在js中如果这个近似值足够近似,那么js就会认为他就是那个值。
(3) 在0.1 + 0.2这个式子中,0.1和0.2都是近似表示的,在他们相加的时候,两个近似值进行了计算,导致最后得到的值是0.30000000000000004,此时对于JS来说,其不够近似于0.3,于是就出现了0.1 + 0.2 != 0.3 这个现象。
当然,有时两个近似值进行计算的时候,得到的值是在JS的近似范围内的,于是就可以得到正确答案。
(4) 解决办法:
就是我们想办法规避掉这类小数计算时的精度问题,那么最常用的方法就是将浮点数转化成整数计算。因为整数都是可以精确表示的。
对于0.1 + 0.02 我们需要转化成 ( 10 + 2 ) / 1e2
公共方法使用
js的数字有一个大小限制,超出会溢出,现写一个 add(num:string,num:string):string 求大数之和栗子:add("2312421212512521111112421412412","123")
float型浮点数相加会出现问题,如0.1+0.3
很正常的,浮点数运算的误差。哪种语言都这样,只是误差大小不同而已。 用解析字符串的方式移动小数点,转化为整数,完毕后,在把小数点复位。 浮点数运算的时候,先转化为二进制,用二进制来算,结果再转回十进制 例如 :求1038.1-1000 1038.1=10000001110.0001100110011001100110011001100110011001100..... 1000= 1111101000 1038.1转化为二进制是个无限循环小数,1100是循环节,只能取近似值,误差就是这里产生的 如果浏览器版本高,可以用toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.后有固定的 num 位数字。如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度。如果 num 大于 le+21,则该方法只调用 NumberObject.toString(),返回采用指数计数法表示的字符串。语法NumberObject.toFixed(num)返回值返回 NumberObject 的字符串表示,不采用指数计数法,小数点后有固定的 num 位数字。如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度。如果 num 大于 le+21,则该方法只调用 NumberObject.toString(),返回采用指数计数法表示的字符串。抛出当 num 太小或太大时抛出异常 RangeError。0 ~ 20 之间的值不会引发该异常。有些实现支持更大范围或更小范围内的值。当调用该方法的对象不是 Number 时抛出 TypeError 异常。在本例中,我们将把数字舍入为仅有一位小数的数字:Show the number 13.37 with one decimal:<script type="text/javascript">var num = new Number(13.37)document.write (num.toFixed(1))</script>输出:Show the number 13.37 with one decimal:13.4