缘由

最近在做公司的一个点餐H5项目需要前端动态计算用户选的商品的总价(单价*数量)和购物车的总价格时发现关于 JavaScript 浮点数计算精度不准确问题。在控制台输入0.1 0.2也能发现此问题。

    // 加法
    0.1   0.2 = 0.30000000000000004
    0.7   0.1 = 0.7999999999999999
    0.2   0.4 = 0.6000000000000001

    // 减法
    1.5 - 1.2 = 0.30000000000000004
    0.3 - 0.2 = 0.09999999999999998
    
    // 乘法
    19.9 * 100 = 1989.9999999999998
    0.8 * 3 = 2.4000000000000004
    35.41 * 100 = 3540.9999999999995

    // 除法
    0.3 / 0.1 = 2.9999999999999996
    0.69 / 10 = 0.06899999999999999

问题的原因

为什么 0.1 0.2 JS加不了? 产生浮点数计算精度不准确的原因: 在计算机角度,计算机算的是二进制,而不是十进制。二进制后变成了无线不循环的数,而计算机可支持浮点数的小数部分可支持到52位,所有两者相加,在转换成十进制,得到的数就不准确了,加减乘除运算原理一样。

十进制 二进制
0.1 0.0001 1001 1001 1001 ...
0.2 0.0011 0011 0011 0011 ...
0.3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0.5 0.1
0.6 0.1001 1001 1001 1001 ...

所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。

最通俗的解释

比如一个数 1÷3=0.33333333...... 大家都知道3会一直无限循环,数学可以表示,但是计算机要存储,方便下次取出来再使用,但0.333333...... 这个数 无限循环,你让计算机怎么存储?计算机再大的内存它也存不下,对吧! 所以不能存储一个相对于数学来说的值,只能存储一个近似值,所以当计算机存储后再取出来用时就会出现精度问题。

解决方案 - Math.js

对于任意精度的计算,math.js 支持BigNumber 数据类型。

安装

npm install mathjs

请注意,在 TypeScript 项目中使用 mathjs 时,您还必须安装类型定义文件:npm install @types/mathjs.

封装

import * as math from 'mathjs';
export default {
    // 加
	add(num1,num2){
		return math.add(math.bignumber(num1),math.bignumber(num2));
	},
	// 乘
	multiply(num1,num2){
		return math.multiply(math.bignumber(num1),math.bignumber(num2));
	},
	// 减
	subtract(num1,num2){
		return math.subtract(math.bignumber(num1),math.bignumber(num2));
	},
	// 除
	divide(num1,num2){
		return math.divide(math.bignumber(num1),math.bignumber(num2));
	}
}

使用

import math from './math.js'
let addNum = math.add(3,2); // 5
let mulNum = math.multiply(3,2); // 6
let subNum = math.subtract(3,2); // 1 
let divNum = math.divide(3,2); // 1.5

附:math.js 大数功能

<script type="text/javascript">
// functions and constants
console.log('mathjs BigNumber eg')
print(math.add(math.bignumber(0.1), math.bignumber(0.2))) // 加法 BigNumber, 0.3
print(math.subtract(math.bignumber(1), math.bignumber(0.9))) // 减法 BigNumber, 0.1
print(math.multiply(math.bignumber(4.10), math.bignumber(100))) // 乘法 BigNumber, 0.1
print(math.ceil(math.bignumber(6.10)/ math.bignumber(0.1)));   //除法 向上取整 61
print(math.floor(math.bignumber(6.10)/ math.bignumber(0.1)));   //除法 向下取整 61
print(math.round(math.bignumber(6.10)/ math.bignumber(0.1)));   // 除法 四舍五入 61
/**
 * Helper function to output a value in the console. Value will be formatted.
 * @param {*} value
 */
function print (value) {
  const precision = 14
  console.log(math.format(value, precision))
}
</script>

总结

到此这篇关于利用Math.js解决JS计算小数精度丢失问题的文章就介绍到这了,更多相关JS计算小数精度丢失内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

利用Math.js解决JS计算小数精度丢失问题的更多相关文章

  1. 利用Math.js解决JS计算小数精度丢失问题

    电商系统中订单、库存中有数字等加减乘除算术,下面这篇文章主要给大家介绍了关于利用Math.js解决JS计算小数精度丢失问题的相关资料,mathjs是一个前端在计算上面必定会用到的类库,需要的朋友可以参考下

  2. 基于jQuery实现文本框只能输入数字(小数、整数)

    在实际应用中,文本框中有时候只能够允许输入整数,但是有时候可能更为"博爱"一点,可以允许输入浮点数,下面就通过实例代码介绍一下如何利用jquery实现此功能

  3. javascript保留两位小数的实现方法你了解吗

    这篇文章主要为大家介绍了javascript保留两位小数的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

  4. 一文教会你解决js数字精度丢失问题

    在JavaScript中计算两个十进制数的和,有时候会出现令人惊讶的结果,相信这个大家也都知道了,下面这篇文章主要给大家介绍了关于解决js数字精度丢失问题的相关资料,需要的朋友可以参考下

  5. JS中浮点数精度问题的分析与解决方法

    在js中我们有时会遇到计算,通过加减乘除处理某些业务,那么这时候如果不做任何处理,就会出现如下典型的精度丢失问题,下面这篇文章主要给大家介绍了关于JS中浮点数精度问题的分析与解决方法,需要的朋友可以参考下

  6. jquery限定文本框只能输入数字(整数和小数)

    这篇文章主要介绍了jquery限定文本框只能输入数字,包括整数和小数,感兴趣的小伙伴们可以参考一下

  7. JS超出精度数字问题的解决方法

    一般参数值不能超过16位,如果超出16都是用0替代,导致我们查询不到自己想要的结果,这篇文章主要给大家介绍了关于JS超出精度数字问题的解决方法,需要的朋友可以参考下

  8. javascript小数四舍五入多种方法实现

    javascript小数四舍五入在工作中经常会使用到,今天本文整理了一些常用的小窍门,需要了解的朋友可以参考下

  9. 利用jquery实现验证输入的是否是数字、小数,包含保留几位小数

    本文主要介绍了利用jquery实现验证输入的是否是数字、小数,包含保留几位小数,代码清晰,容易理解。有需要的朋友可以参考下

  10. SpringBoot2.0解决Long型数据转换成json格式时丢失精度问题

    这篇文章主要介绍了SpringBoot2.0解决Long型数据转换成json格式时丢失精度问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部