”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 超越 JavaScript - 为什么 + 在编程中不等于

超越 JavaScript - 为什么 + 在编程中不等于

发布于2024-11-01
浏览:672

当开发者第一次遇到这个看似令人费解的结果时,JavaScript 经常被嘲笑:

0.1   0.2 == 0.30000000000000004

关于 JavaScript 处理数字的模因很普遍,常常导致许多人相信这种行为是该语言所独有的。

Beyond JavaScript - Why     doesn

然而,这个怪癖不仅仅局限于 JavaScript。这是大多数编程语言处理浮点运算方式的结果。

例如,以下是来自 JavaGo 的代码片段,它们产生类似的结果:

Beyond JavaScript - Why     doesn

Beyond JavaScript - Why     doesn

计算机本身只能存储整数。他们不懂分数。 (他们会怎么做?计算机进行算术运算的唯一方法是打开或关闭一些灯。灯可以打开或关闭。它不能“半”亮!)他们需要某种表示浮点数的方法。由于这种表示方法并不完全准确,因此 0.1 0.2 通常不等于 0.3。

所有分母由数系基数的质因数组成的分数都可以清晰地表达,而任何其他分数都会有重复的小数。例如,在以 10 为基数的数字系统中,可以清楚地表示 1/2、1/4、1/5、1/10 等分数,因为每种情况下的分母均由 2 或 5(10 的质因数)组成然而,像 1/3、1/6、1/7 这样的分数都有循环小数。

同样,在二进制系统中,像 1/2、1/4、1/8 这样的分数都可以清晰地表达,而所有其他分数都有循环小数。当您对这些循环小数执行算术运算时,您最终会得到剩余的内容,当您将计算机的数字二进制表示形式转换为人类可读的以 10 为基数的表示形式时,这些剩余内容会继续存在。这就是导致大致正确结果的原因。

既然我们已经确定这个问题并非 JavaScript 所独有,那么让我们探讨一下浮点数是如何在幕后表示和处理的,以了解为什么会出现这种行为。

为了了解浮点数在底层是如何表示和处理的,我们首先必须了解IEEE 754浮点标准。

IEEE 754 标准是一种广泛使用的规范,用于在计算机系统中表示浮点数并对其执行算术运算。它的创建是为了保证在各种计算平台上使用浮点运算时的一致性。大多数编程语言和硬件实现(CPU、GPU 等)都遵守此标准。

这是数字在 IEEE 754 格式中的表示方式:

Beyond JavaScript - Why     doesn

这里s是符号位(0表示正数,1表示负数),M是尾数(保存数字的位数)和E 是决定数字小数位数的指数。

您将无法找到任何可以在此格式中精确表示数字(如 0.1、0.2 或 0.3)的 M 和 E 整数值。我们只能选择给出最接近结果的 M 和 E 值。

这里有一个工具,您可以用来确定 IEEE 754 十进制数表示法:https://www.h-schmidt.net/FloatConverter/IEEE754.html

IEEE 754 0.25 表示法:

Beyond JavaScript - Why     doesn

IEEE 754 分别表示 0.1 和 0.2:

Beyond JavaScript - Why     doesn
Beyond JavaScript - Why     doesn

请注意,0.25时转换误差为0,而0.1和0.2则为非零误差。

IEEE 754 定义了以下表示浮点数的格式:

  • 单精度(32 位):1 位符号,8 位指数,23 位尾数

  • 双精度(64 位):1 位符号,11 位指数,52 位尾数

为了简单起见,让我们考虑使用 32 位的单精度格式。

0.1的32位表示为:

0 01111011 10011001100110011001101

这里第一位代表符号(0在本例中表示正数),接下来的8位(01111011)代表指数,最后23位(10011001100110011001101)代表尾数。

这不是准确的表示。它代表 ≈ 0.100000001490116119384765625

同样,0.2的32位表示为:

0 01111100 10011001100110011001101

这也不是准确的表示。它代表 ≈ 0.20000000298023223876953125

添加后,结果是:

0 01111101 11001101010011001100110 

十进制表示中的 ≈ 0.30000001192092896

总之,看似令人困惑的结果 0.1 0.2 不产生 0.3 并不是 JavaScript 特有的异常现象,而是跨编程语言的浮点运算限制的结果。这种行为的根源在于数字的二进制表示形式,这在处理某些分数时本质上会导致精度错误。

版本声明 本文转载于:https://dev.to/umangsinha12/beyond-javascript-why-01-02-doesnt-equal-03-in-programming-2bf3?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-05-07
  • 在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在C中的显式删除 在C中的动态内存分配时,开发人员通常会想知道是否有必要在heap-procal extrable exit exit上进行手动调用“ delete”操作员,但开发人员通常会想知道是否需要手动调用“ delete”操作员。本文深入研究了这个主题。 在C主函数中,使用了动态分配变量(H...
    编程 发布于2025-05-07
  • `console.log`显示修改后对象值异常的原因
    `console.log`显示修改后对象值异常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    编程 发布于2025-05-07
  • 如何高效地在一个事务中插入数据到多个MySQL表?
    如何高效地在一个事务中插入数据到多个MySQL表?
    mySQL插入到多个表中,该数据可能会产生意外的结果。虽然似乎有多个查询可以解决问题,但将从用户表的自动信息ID与配置文件表的手动用户ID相关联提出了挑战。使用Transactions和last_insert_id() 插入用户(用户名,密码)值('test','test...
    编程 发布于2025-05-07
  • eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    称量()和ast.literal_eval()中的Python Security 在使用用户输入时,必须优先确保安全性。强大的Python功能Eval()通常是作为潜在解决方案而出现的,但担心其潜在风险。 This article delves into the differences betwee...
    编程 发布于2025-05-07
  • 如何在GO编译器中自定义编译优化?
    如何在GO编译器中自定义编译优化?
    在GO编译器中自定义编译优化 GO中的默认编译过程遵循特定的优化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    编程 发布于2025-05-07
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-05-07
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,输出...
    编程 发布于2025-05-07
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-05-07
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-05-07
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] 剩余_size- = buf_size lines = buffer.split('\ n'....
    编程 发布于2025-05-07
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-05-07
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-05-07
  • 查找当前执行JavaScript的脚本元素方法
    查找当前执行JavaScript的脚本元素方法
    如何引用当前执行脚本的脚本元素在某些方案中理解问题在某些方案中,开发人员可能需要将其他脚本动态加载其他脚本。但是,如果Head Element尚未完全渲染,则使用document.getElementsbytagname('head')[0] .appendChild(v)的常规方...
    编程 发布于2025-05-07
  • 如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    编程 发布于2025-05-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3