为什么使用 toFixed 方法的结果不一致呢?

偶遇一个不准确的方法 toFixed() ,其是 JS 中用于将数字格式化为指定小数位数的方法,但有时返回的结果不够准确,展示如下:

这通常是由于 JavaScript 对浮点数的处理方式导致的。

1. 浮点数精度问题

JavaScript 中的数字是以 IEEE 754 双精度浮点数 格式存储的,遵循64位的二进制浮点数表示。这种表示方式虽然能精确表示一些数值(如整数),但对某些小数(如 0.1 或 0.2 等)无法精确表示,它们会被存储为近似值。这是因为在二进制中,有些小数无法被精确地表示,导致了舍入误差。

🌰

这里 0.1 + 0.2 并不是精确的 0.3,而是稍微大于 0.3 的近似值。这种舍入误差是由于浮点数在二进制中表示精度不足造成的。

分析:

1、存储不精确

计算机存储的是二进制格式,不能存储无限小数,需要进行截断处理,导致第一步存储不精确,截断之后为 1 进一位,截断之后为 0 保留位。

2、运算不精确

因为存储的问题,进一步导致运算出问题,但不是绝对的,可能会抵消。

3、显示不精确

浏览器会进行近似处理,而不是完全展示真实数据。

一个神奇的现象,两个不一样的数据居然返回为 true。 

2. toFixed() 的行为

toFixed() 方法会将一个数字四舍五入为指定的小数位数,然后返回字符串形式的结果。

虽然它的作用看起来很简单,但由于浮点数的精度问题,有时会返回意料之外的结果。尤其是当浮点数内部表示的近似值超出人们期望时,toFixed() 会将这个误差传播到结果中。

🌰:

在 1.005 的例子中,浮点数舍入时引入了误差,toFixed(2) 结果会让人觉得舍入有问题,然而这是浮点数精度不足的体现。

十进制位数不同导致精度最后取舍有问题,究竟是1100的循环还是0011还是其他,影响不大。

3. 如何解决 toFixed 精度不准的问题

要解决浮点数精度问题,可以采用以下几种方法:

1、手动控制四舍五入的逻辑

function toFixedFix(num, decimalPlaces) {
  const factor = Math.pow(10, decimalPlaces);
  return (Math.round((num + Number.EPSILON) * factor) / factor).toFixed(decimalPlaces);
}

console.log(toFixedFix(1.005, 2));  // 输出 1.01
console.log(toFixedFix(10.235, 2));  // 输出 10.24

2、使用第三方库

由于 JavaScript 内置的浮点数精度问题,一些库提供了更加精确的数值处理方法,尤其适用于财务计算等对精度要求较高的场景。

🌰:BigNumber、Decimal,它可以精确处理任意大小和精度的数字。

// npm install bigdecimal.js
const BigDecimal = require('bigdecimal.js');

function toFixedBigDecimal(num, decimalPlaces) {
  const bigNum = new BigDecimal(num.toString());
  return bigNum.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).toString();
}

console.log(toFixedBigDecimal(1.005, 2)); // 输出 1.01
console.log(toFixedBigDecimal(10.235, 2)); // 输出 10.24

这些库通过不同的底层实现来避免 JavaScript 浮点数的精度问题,并提供更多精确的数值操作方法。

3、使用字符串运算解决浮点误差

可以通过将数字转换为字符串,避免浮点数计算的问题。

function toFixedString(num, decimalPlaces) {
  let [integerPart, decimalPart] = num.toString().split('.');
  if (decimalPart && decimalPart.length > decimalPlaces) {
    // 提取多余的位数进行四舍五入操作
    const roundingDigit = parseInt(decimalPart[decimalPlaces], 10);
    decimalPart = decimalPart.slice(0, decimalPlaces);
    if (roundingDigit >= 5) {
      decimalPart = (parseInt(decimalPart, 10) + 1).toString();
    }
  }
  return parseFloat(integerPart + '.' + decimalPart).toFixed(decimalPlaces);
}

console.log(toFixedString(1.005, 2)); // 输出 1.01
console.log(toFixedString(10.235, 2)); // 输出 10.24

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/900489.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

乡村小道图像分割系统:智能化检测

乡村小道图像分割系统源码&数据集分享 [yolov8-seg-C2f-Faster-EMA&yolov8-seg-HGNetV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Globa…

JavaWeb合集22-Apache POI

二十二、Apache POI Apache POI是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用POI在Java 序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI都是用于操作Excel文件。 使用场景:银行网银系统导出…

Unity Vision Pro 保姆级开发教程-PolySpatial VisionOS Samples 示例场景

视频教程地址 PolySpatial VisionOS Samples 示例场景 Unity Vision Pro 中文课堂教程地址: Unity3D Vision Pro 开发教程【保姆级】 | Unity 中文课堂 有界体积样本 Balloon Gallery 气球画廊 气球画廊是一个迷你游戏,演示了使用Indirect Pinch and …

vue3使用i18n做国际化多语言,实现常量跟随语言切换翻译

因为我有一个常量的配置文件在项目中,而且有中文内容,我想在切换语言的时候,跟着这个翻译也实时切换,就可以使用computed计算属性实现。 把name改成下面的样子: name: computed(() > t(pad.regularMode)), 就可以…

基于SpringBoot的人才公寓管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

一个包含了超过 200 个实用脚本的 Python 脚本库,如文件管理、网络操作、图像处理、文本处理等

前言 在日常的工作和生活中,我们经常会遇到一些重复性的任务,如文件管理、网络cao作、图像处理、文本处理等。这些任务虽然简单,但如果频繁手动cao作,不仅耗时耗力,还容易出错。 现有的软件虽然能处理一部分问题&…

Vue2+Univer 环境搭建

node js 版本 16.32 参考文档: Vue2Univer实现可编辑Excel_vue univer-CSDN博客 https://univer.ai/guides/sheet/getting-started/quickstart 实现步骤: 1、包里面直接写这些 "riophae/vue-treeselect": "0.4.0","univ…

基于深度学习的图像修复系统设计与实现(PyQt5、CodeFormer ffhq-dataset数据集)

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

Matlab 车牌识别技术

1.1设计内容及要求: 课题研究的主要内容是对数码相机拍摄的车牌,进行基于数字图像处理技术的车牌定位技术和车牌字符分割技术的研究与开发,涉及到图像预处理、车牌定位、倾斜校正、字符分割等方面的知识,总流程图如图1-1所示。 图1-1系统总…

为什么自动化测试落地这么难?

最近一直在想一个问题,就是自动化测试落地为什么这么难? 想要找到原因首先我们要明确实施自动化测试的目的,价值,以及要解决的问题是什么?然后我们可以再进一步分析为什么自动化测试很难落地? 实施自动化…

数据采集与数据分析:数据时代的双轮驱动

“在当今这个数据驱动的时代,信息已成为企业决策、市场洞察、科学研究等领域不可或缺的核心资源。而爬虫数据采集与数据分析,作为数据处理链条上的两大关键环节,它们之间相辅相成,共同构成了数据价值挖掘的强大引擎。” 爬虫数据采…

【js逆向专题】12.RPC技术

目录 一. websocket1. 什么是websocket2. websocket的原理3. websocket实现方式1. 客户端2.服务端3. 实际案例1. 案例目标2. 解析思路 二. RPC1. RPC 简介2.Sekiro-RPC1. 使用方法1. 执行方式2.客户端环境3.使用参数说明 2. 测试使用1. 前端代码2. SK API3.python调用代码 三.项…

AR模型时序预测——预测未来(含完整代码)

一、前言 随着数据科学的快速发展,利用自回归(AR)模型进行时序预测已成为一个热门话题。AR模型因其简洁有效,广泛应用于各类预测任务。本文将介绍一套基于Matlab的AR模型时序预测代码,重点在于如何通过历史数据预测未…

工业相机详解及选型

工业相机相对于传统的民用相机而言,具有搞图像稳定性,传输能力和高抗干扰能力等,目前市面上的工业相机大多数是基于CCD(Charge Coupled Device)或CMOS(Complementary Metal Oxide Semiconductor)芯片的相机。 一,工业相机的分类 …

爬虫+数据保存

爬虫以及数据保存 这篇文章, 分享如何将爬虫爬到的数据, 保存到excel表格当中。 文章目录 1.安装保存数据的第三方库openpyxl并使用 2.爬虫加单表数据保存 3.爬虫加多表数据保存 4.实战 一、安装保存数据的第三方库openpyxl并使用 我们需要安装openpyxl的第三方库 安装…

01 springboot-整合日志(logback-config.xml)

logback-config.xml 是一个用于配置 Logback 日志框架的 XML 文件,通常位于项目的 classpath 下的根目录或者 src/main/resources 目录下。 Logback 提供了丰富的配置选项,可以满足各种不同的日志需求。需要根据具体情况进行配置。 项目创建&#xff0…

打造充电场站:场地选择与合规运营详解

建设一座充电站需要六步流程:准备工作 → 备案 → 土地审核 → 规划审核 → 电力申请 → 验收确认 一、准备工作 在确定建设前,要考察待选的场地,例如空地、停车场等,与场地所有方签订充电站建设合作协议。根据场地和车流量等实际…

用docker Desktop 下载使用thingsboard/tb-gateway

1、因为正常的docker pull thingsboard/tb-gateway 国内不行了,所以需要其它工具来下载 2、在win下用powershell管理员下运行 docker search thingsboard/tb-gateway 可以访问到了 docker pull thingsboard/tb-gateway就可以下载了 3、docker Desktop就可以看到…

铲屎官进!双十一宠物空气净化器买哪款,有什么推荐的吗?

害,一到换毛季,真的顶不顺!家里两只布偶疯狂掉毛,地板、衣服上这些常规的地方就不用说了,竟然连水杯旁也有浮毛的存在,被我不小心喝进去好几次,最严重的时候已经猫毛拌饭了。 我寻求了很多解决方…

jQuery:动画 节点

jQuery:动画 & 节点 定位获取位置滚动距离 动画显示隐藏淡入淡出展开收起动画队列自定义动画动画回调函数动画延迟 节点插入节点删除节点 定位 获取位置 jquery提供了两个方法,来获取元素所处的位置: // 取值 jQuery对象.offset() // …