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

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

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

当开发者第一次遇到这个看似令人费解的结果时,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]删除
最新教程 更多>
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-04-11
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-04-11
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-11
  • 如何在php中使用卷发发送原始帖子请求?
    如何在php中使用卷发发送原始帖子请求?
    如何使用php 然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头的数组使用curlopt_httpheader选项:响应将存储在变量$ result。示例代码...
    编程 发布于2025-04-11
  • Android如何向PHP服务器发送POST数据?
    Android如何向PHP服务器发送POST数据?
    在android apache httpclient(已弃用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    编程 发布于2025-04-11
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-04-11
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    编程 发布于2025-04-11
  • 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-04-11
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-11
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-04-11
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-04-11
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-04-11
  • 如何使用Python理解有效地创建字典?
    如何使用Python理解有效地创建字典?
    在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
    编程 发布于2025-04-11
  • 为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    查询模式实现缺失:解决“无法找到”错误在银光应用程序中,尝试使用LINQ建立错误的数据库连接的尝试,无法找到以查询模式的实现。”当省略LINQ名称空间或查询类型缺少IEnumerable 实现时,通常会发生此错误。 解决问题来验证该类型的质量是至关重要的。在此特定实例中,tblpersoon可能需...
    编程 发布于2025-04-11
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-04-11

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

Copyright© 2022 湘ICP备2022001581号-3