13-为什么在JavaScript中0.1 + 0.2不等于0.3?

2024-06-04 09:28
文章标签 java script 等于 0.1 13 0.2 0.3

本文主要是介绍13-为什么在JavaScript中0.1 + 0.2不等于0.3?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为什么在JavaScript中0.1 + 0.2不等于0.3?

笔记+分享
在编写JavaScript代码时,你可能会遇到一个奇怪的现象:0.1 + 0.2并不等于0.3。这个问题并不仅仅局限于JavaScript,它在许多编程语言中都会出现。本文将解释背后的原因,并探讨如何处理这个问题。

浮点数的表示

首先,我们需要了解计算机是如何表示小数的。计算机使用二进制(base-2)来表示所有数据,包括小数。而在二进制中,并不是所有的十进制小数都能精确地表示。

在十进制系统中,0.1可以表示为1/10。但是,在二进制系统中,0.1表示为一个无限循环的小数,类似于在十进制中1/3表示为0.3333…。二进制中的0.1表示为0.0001100110011001100110011001100...(循环)。

IEEE 754标准

JavaScript(以及大多数编程语言)使用IEEE 754标准来表示浮点数。这是一种二进制浮点数表示方法,包括32位和64位两种格式。JavaScript使用64位双精度格式。

在IEEE 754标准下,浮点数表示为:

  • 1位符号位(0表示正,1表示负)
  • 11位指数位
  • 52位尾数位(加上隐含的1位)

对于像0.1和0.2这样的数字,这种表示方法会导致精度损失。将这些十进制小数转换为二进制浮点数时,它们只能近似表示。这种近似表示导致了0.1 + 0.2的结果不完全等于0.3。

具体示例

让我们看一个具体的例子:

  • 0.1在二进制浮点数中的近似表示是:0.00011001100110011001100110011001100110011001100110011
  • 0.2在二进制浮点数中的近似表示是:0.001100110011001100110011001100110011001100110011001101

当你将这两个值相加时,得到的结果是:

  • 0.1 + 0.2 ≈ 0.30000000000000004

这并不是精确的0.3,而是一个非常接近0.3的数值,但在计算机的精度限制下,它们并不相等。

处理浮点数精度问题

为了在JavaScript中正确处理浮点数的精度问题,可以采取以下方法:

  1. 使用容差值进行比较
    由于直接比较浮点数可能会失败,使用一个非常小的容差值来判断两个浮点数是否接近。

    const a = 0.1;
    const b = 0.2;
    const sum = a + b;
    const epsilon = 0.0000001;if (Math.abs(sum - 0.3) < epsilon) {console.log('0.1 + 0.2 is approximately equal to 0.3');
    } else {console.log('0.1 + 0.2 is not equal to 0.3');
    }
    
  2. 使用整数运算
    将浮点数转换为整数进行运算,然后再将结果转换回浮点数。这在涉及货币计算时特别有用。

    const a = 0.1 * 100; // 10
    const b = 0.2 * 100; // 20
    const sum = a + b; // 30console.log(sum / 100); // 0.3
    
  3. 使用BigDecimal库
    对于需要高精度计算的场景,可以使用BigDecimal库进行处理,这些库能够精确处理十进制数。

    // 使用BigDecimal.js库
    const Big = require('big.js');
    const a = new Big(0.1);
    const b = new Big(0.2);
    const sum = a.plus(b);console.log(sum.toString()); // 0.3
    

结论

0.1 + 0.2不等于0.3的原因在于计算机使用二进制浮点数表示小数时存在精度损失。理解这一点,并采用适当的方法来处理浮点数计算,可以帮助我们避免相关的精度问题。在日常开发中,了解并合理处理这种精度问题至关重要。

这篇关于13-为什么在JavaScript中0.1 + 0.2不等于0.3?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1029692

相关文章

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

浅析Java中如何优雅地处理null值

《浅析Java中如何优雅地处理null值》这篇文章主要为大家详细介绍了如何结合Lambda表达式和Optional,让Java更优雅地处理null值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录场景 1:不为 null 则执行场景 2:不为 null 则返回,为 null 则返回特定值或抛出异常场景

SpringMVC获取请求参数的方法

《SpringMVC获取请求参数的方法》:本文主要介绍SpringMVC获取请求参数的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下... 目录1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、@RequestParam4、@

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

SpringBoot条件注解核心作用与使用场景详解

《SpringBoot条件注解核心作用与使用场景详解》SpringBoot的条件注解为开发者提供了强大的动态配置能力,理解其原理和适用场景是构建灵活、可扩展应用的关键,本文将系统梳理所有常用的条件注... 目录引言一、条件注解的核心机制二、SpringBoot内置条件注解详解1、@ConditionalOn

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Spring LDAP目录服务的使用示例

《SpringLDAP目录服务的使用示例》本文主要介绍了SpringLDAP目录服务的使用示例... 目录引言一、Spring LDAP基础二、LdapTemplate详解三、LDAP对象映射四、基本LDAP操作4.1 查询操作4.2 添加操作4.3 修改操作4.4 删除操作五、认证与授权六、高级特性与最佳

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

SpringSecurity JWT基于令牌的无状态认证实现

《SpringSecurityJWT基于令牌的无状态认证实现》SpringSecurity中实现基于JWT的无状态认证是一种常见的做法,本文就来介绍一下SpringSecurityJWT基于令牌的无... 目录引言一、JWT基本原理与结构二、Spring Security JWT依赖配置三、JWT令牌生成与