IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> js中浮点数的计算(求和) -> 正文阅读

[JavaScript知识库]js中浮点数的计算(求和)

问题描述

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

  • 浮点数精度问题,比如 0.1 + 0.2 !== 0.3

解决方案

demo地址

在这里插入图片描述

把浮点数转化为字符串,模拟实际运算的过程。

import React, { useState } from 'react';
import { InputNumber } from 'antd';
import styles from './FloatNumSum.less';

export interface FloatNumSumProps extends React.HTMLAttributes<HTMLDivElement> {}

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 (
    <div className={`${styles.root} ${className}`} {...otherProps}>
      <InputNumber min={0} value={floatNumList[0]} onChange={(e) => onChange(e, 0)} />
      <InputNumber min={0} value={floatNumList[1]} onChange={(e) => onChange(e, 1)} />
      <InputNumber min={0} value={floatNumList[2]} onChange={(e) => onChange(e, 2)} />
      <h3></h3>
      <h3>javascriot的计算结果:</h3>
      <div>{`${floatNumList[0]}+${floatNumList[1]}+${floatNumList[2]}=${sumJs()}`}</div>
      <h3>优化后的计算结果:</h3>
      <div>{`${floatNumList[0]}+${floatNumList[1]}+${floatNumList[2]}=${sum()}`}</div>
    </div>
  );
};

export default FloatNumSum;

其他方案

如何解决浮点数运算的精度问题,有 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.jsdecimal.js,以及big.js等。我们可以根据自己的需求来选择对应的工具。并且,这些库不仅解决了浮点数的运算精度问题,还支持了大数运算,并且修复了原生toFixed结果不准确的问题。

参考资料

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

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:33:45  更:2022-04-26 11:37:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:42:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码