js中浮点数的计算(求和)

您所在的位置:网站首页 整数和浮点数相加等于多少怎么计算 js中浮点数的计算(求和)

js中浮点数的计算(求和)

2024-07-10 04:35| 来源: 网络整理| 查看: 265

问题描述

js中的浮点数有精度问题:

浮点数精度问题,比如 0.1 + 0.2 !== 0.3 解决方案

demo地址

在这里插入图片描述

import React, { useState } from 'react'; import { InputNumber } from 'antd'; import NP from 'number-precision'; import styles from './FloatNumSum.less'; export interface FloatNumSumProps extends React.HTMLAttributes {} const FloatNumSum = (props: FloatNumSumProps) => { const { className = '', ...otherProps } = props; const [floatNumList, setFloatNumList] = useState([1.1, 1.2, 1.3]); const sumFloatNum = (x: number, y: number) => { const stringX = `${x}`; const stringY = `${y}`; const integerX = stringX.includes('.') ? stringX.split('.')[0] : x; const decimalX = stringX.includes('.') ? stringX.split('.')[1] : 0; const integerY = stringY.includes('.') ? stringY.split('.')[0] : y; const decimalY = stringY.includes('.') ? stringY.split('.')[1] : 0; return Number(`${Number(integerX) + Number(integerY)}.${Number(decimalX) + Number(decimalY)}`); }; const sum = () => { return floatNumList.reduce((x, y) => { return sumFloatNum(x, y); }); }; const sumJs = () => { return floatNumList.reduce((x, y) => x + y); }; function onChange(value: number, index: number) { const newFloatNumList = [...floatNumList]; newFloatNumList[index] = value; setFloatNumList(newFloatNumList); } return ( onChange(e, 0)} /> onChange(e, 1)} /> onChange(e, 2)} /> 原生javascriot的计算结果: {`${floatNumList[0]}+${floatNumList[1]}+${floatNumList[2]}=${sumJs()}`} number-precision的计算结果: {`${floatNumList[0]}+${floatNumList[1]}+${floatNumList[2]}=${NP.plus( ...floatNumList, )}`} 自定义方法的计算结果(不支持进位,位数要相同,仅做示意): {`${floatNumList[0]}+${floatNumList[1]}+${floatNumList[2]}=${sum()}`} ); }; export default FloatNumSum;

浮点数的求和,sumFloatNum方法不支持进位

其他方案

如何解决浮点数运算的精度问题,有 3 种思路:

考虑到每次浮点数运算的偏差非常小(其实不然),可以对结果进行指定精度的四舍五入,比如可以parseFloat(result.toFixed(12));将浮点数转为整数运算,再对结果做除法。比如0.1 + 0.2,可以转化为(1*2)/3。把浮点数转化为字符串,模拟实际运算的过程。

先来看第一种方案,在大多数情况下,它可以得到正确结果,但是对一些极端情况,toFixed 到 12 是不够的,比如:

210000 * 10000 * 1000 * 8.2 // 17219999999999.998 parseFloat(17219999999999.998.toFixed(12)); // 17219999999999.998,而正确结果为 17220000000000

上面的情况,如果想让结果正确,需要 toFixed(2),这显然是不可接受的。

再看第二种方案,比如 number-precision 这个库就是使用的这种方案,但是这也是有问题的,比如:

// 这两个浮点数,转化为整数之后,相乘的结果已经超过了 MAX_SAFE_INTEGER 123456.789 * 123456.789 // 转化为 (123456789 * 123456789)/1000000,结果是 15241578750.19052

所以,最终考虑使用第三种方案,目前已经有了很多较为成熟的库,比如 bignumber.js,decimal.js,以及big.js等。我们可以根据自己的需求来选择对应的工具。并且,这些库不仅解决了浮点数的运算精度问题,还支持了大数运算,并且修复了原生toFixed结果不准确的问题。

参考资料

JavaScript 中精度问题以及解决方案



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3