浮点数学有问题吗?

2024-02-09

考虑以下代码:

0.1 + 0.2 == 0.3  ->  false
0.1 + 0.2         ->  0.30000000000000004

为什么会出现这些不准确的情况?


Binary 浮点 https://en.wikipedia.org/wiki/Double-precision_floating-point_format数学就是这样。在大多数编程语言中,它基于IEEE 754 标准 https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats。问题的关键在于,数字以这种格式表示为整数乘以 2 的幂;有理数(例如0.1,即1/10) 的分母不是 2 的幂,无法精确表示。

For 0.1在标准中binary64格式,表示可以完全写为

  • 0.1000000000000000055511151231257827021181583404541015625以十进制表示,或
  • 0x1.999999999999ap-4 in C99 十六进制浮点表示法 http://www.exploringbinary.com/hexadecimal-floating-point-constants/.

相比之下,有理数0.1,即1/10,可以完全写成

  • 0.1以十进制表示,或
  • 0x1.99999999999999...p-4与 C99 十六进制浮点表示法类似,其中...表示一个无休止的 9 序列。

常数0.2 and 0.3您的程序中的值也将是其真实值的近似值。碰巧的是,最近的double to 0.2大于有理数0.2但最接近的double to 0.3小于有理数0.3。总数是0.1 and 0.2最终大于有理数0.3因此不同意代码中的常量。

对浮点算术问题的相当全面的处理是每个计算机科学家都应该了解的浮点运算知识 http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html。有关更容易理解的解释,请参阅浮点指南.de http://floating-point-gui.de.

旁注:所有位置(以 N 为基数)数字系统都存在这个精确问题

普通的旧十进制(以 10 为基数)数字也有同样的问题,这就是为什么像 1/3 这样的数字最终会变成 0.333333333...

您刚刚偶然发现了一个数字 (3/10),它很容易用十进制表示,但不适合二进制系统。它也是双向的(在某种程度上):1/16 在十进制中是一个丑陋的数字(0.0625),但在二进制中它看起来像十进制的第 10,000 个(0.0001)** - 如果我们在由于我们在日常生活中使用以 2 为基数的数字系统的习惯,你甚至会看到这个数字并本能地理解你可以通过将某个东西减半、再减半、一次又一次地达到这个数字。

当然,这并不完全是浮点数在内存中的存储方式(它们使用科学记数法的形式)。然而,它确实说明了二进制浮点精度误差往往会出现,因为我们通常感兴趣的“现实世界”数字通常是十的幂 - 但这只是因为我们使用十进制数字系统日 -今天。这也是为什么我们会说 71%,而不是“每 7 中就有 5”(71% 是一个近似值,因为 5/7 无法用任何十进制数精确表示)。

所以不:二进制浮点数并没有被破坏,它们只是碰巧和其他所有基于 N 的数字系统一样不完美:)

旁注:在编程中使用浮点

实际上,这种精度问题意味着您需要使用舍入函数将浮点数舍入到您感兴趣的小数位数,然后再显示它们。

您还需要用允许一定程度容差的比较来替换相等测试,这意味着:

Do not do if (x == y) { ... }

相反做if (abs(x - y) < myToleranceValue) { ... }.

where abs是绝对值。myToleranceValue需要根据您的特定应用进行选择 - 这与您准备允许的“回旋空间”有很大关系,以及您要比较的最大数字可能是多少(由于精度损失问题) )。请注意您选择的语言中的“epsilon”样式常量。这些can用作容差值,但它们的有效性取决于您正在使用的数字的大小(大小),因为大数字的计算可能会超出 epsilon 阈值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浮点数学有问题吗? 的相关文章

  • Windows 应用程序事实上的标准键盘快捷键列表?

    假设我正在为 Windows 开发一个新的桌面应用程序 是否有我可以查阅的所有 Windows 应用程序都应支持的键盘快捷键列表 来自 Microsoft 或第三方 注意 当我在这里说 所有 Windows 应用程序 时 我的真正意思是 特
  • Exposé 布局算法

    我正在制作一些项目 其布局类似于 Mac OS X 在 Expos 中对窗口所做的操作 它适应项目的长宽比和可用区域的长宽比 基本上 可用区域分为行和列 每个单元格 行和列的交集 中放置一个项目 这些项目必须保持其纵横比 此处width h
  • 在 C# 中存储矩阵值的快速且有用的方法

    我需要用 C 为 3D 引擎创建一个 4x4 矩阵类 我见过一些其他引擎将矩阵值存储在单个浮点成员变量 字段中 如下所示 float m11 m12 m13 m14 float m21 m22 m23 m24 float m31 m32 m
  • 将两个 Int 值相除以获得 Float 的正确方法是什么?

    我想分两份IntHaskell 中的值并获得结果Float 我尝试这样做 foo Int gt Int gt Float foo a b fromRational a b 但 GHC 版本 6 12 1 告诉我 无法将预期类型 Intege
  • 在 C# 中生成随机浮点数的最佳方法[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在 C 中生成随机浮点数的最佳方法是什么 更新 我想要从 float Minvalue 到 float Maxvalue 的随机浮点数 我在一些
  • GCC的sqrt()编译后如何工作?使用哪种root方法?牛顿-拉夫森?

    只是对标准感到好奇sqrt 来自 GCC 上的 math h 我自己编码的sqrt 使用牛顿拉夫森来做到这一点 是的 我知道 fsqrt 但CPU是如何做到这一点的呢 我无法调试硬件 现代 CPU 中的典型 div sqrt 硬件使用 2
  • 计算两点之间的最短路线

    过去几周我一直在开发一款多人 HTML5 游戏 使用nodejs and websockets 我已经被这个问题困扰了一段时间 想象一下 我用数组实现了这个平铺地图 如下所示 1 or 棕色瓷砖 路上有障碍物 玩家无法通过 0 or 绿色瓷
  • C++ 中求幂的函数是什么?

    如何计算一个数的幂 2 1 2 2 2 3 etc cmath 库中的 pow 更多信息here http en cppreference com w cpp numeric math pow 别忘了放 include
  • 比较批处理文件中的两个数字

    我在这个网站上搜索了我的问题 但没有找到解决我问题的方法 系统为玩家和计算机提供一个从 2 到 12 的随机数 这有 3 部分 X 大于 Y 如果 X 小于 Y 以及当 X 与 Y 相同 当我开始 bat 效果很好 我选择Play Game
  • 如何在C++中生成高精度的随机双数?

    我正在尝试生成一系列高精度的双随机数 例如 0 856365621 小数点后有 9 位数字 我从网上找到了一些方法 但是 它们确实生成了双随机数 但精度没有我要求的那么好 只有小数点后6位 那么 我可以知道如何实现我的目标吗 在 C 11
  • 过程式编程与 OOP 的开发成本?

    我有相当深厚的 OO 背景 OOD 和 OOP 的好处对我来说是第二天性 但最近我发现自己在一家与过程编程习惯相关的开发商店 实现语言具有一些 OOP 功能 但它们没有以最佳方式使用 更新 每个人似乎对这个话题都有自己的看法 我也是如此 但
  • 在 Blackberry 4.2 JDE 上调用 atan 函数

    我需要从我的 Blackberry Java 应用程序计算反正切值 不幸的是 blackberry 4 2 api 没有 Math atan 函数 Blackberry JDE 4 6 版有此功能 但 4 2 版没有 有谁知道计算 atan
  • 负整数的基数排序

    我正在尝试对整数 包括负整数 实现基数排序 对于非负整数 我计划为数字0 9创建一个10个队列的队列 并实现LSD算法 但我对负整数有点困惑 我现在的想法是继续为它们创建另一个包含 10 个队列的队列 并分别对它们进行排序 然后在最后 我将
  • python:查找围绕某个 GPS 位置的圆的 GPS 坐标的优雅方法

    我有一组以十进制表示的 GPS 坐标 并且我正在寻找一种方法来查找每个位置周围半径可变的圆中的坐标 这是一个例子 http green and energy com downloads test circle html我需要什么 这是一个圆
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 如何翻转双精度数的指数(例如 1e300->1e-300)?

    我有兴趣编写一个快速的 C 程序来翻转双精度数的指数 例如 该程序应将 1e300 转换为 1e 300 我想最好的方法是一些位运算 但我缺乏足够的知识来实现 这一点 有什么好主意吗 假设您要对小数指数求负 则科学记数法中十次方的指数 in
  • C++ Exp 与 Log:哪个更快?

    我有一个 C 应用程序 需要比较两个值并决定哪个值更大 唯一的复杂之处是一个数字在对数空间中表示 而另一个则不是 例如 double log num 1 log 1 23 double num 2 1 24 如果我想比较num 1 and
  • 将名称字符串编码为唯一的数字

    我有一大堆名字 数以百万计 他们每个人都有一个名字 一个可选的中间名和一个姓氏 我需要将这些名称编码为唯一代表这些名称的数字 编码应该是一对一的 即一个名称只能与一个数字相关联 一个数字只能与一个名称相关联 对此进行编码的明智方法是什么 我
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题

随机推荐

  • 如何在 TFS Build 2010 中进行构建定义,可配置 w.r.t 输入变量值和“要构建的项目”

    我们使用 TFS Build 2010 进行构建 我们有两个源代码分支 假设branchA 和branchB Now as a part of the build definition we set the projects to buil
  • 如何让 jQuery 在失败时自动重试 load()?

    我正在页面上的许多地方通过 jquery load 进行一些内容替换 在我的开发服务器上一切正常 在我的实时服务器上 有时它会给我一个 请求无效 错误 我可以在 firebug 中看到该错误 我认为服务器已经不堪重负 或者某些缓存模块可能与
  • Github Actions:检查步骤状态

    我在 CI 工作中的一些步骤可能会引发错误 我不想在出现错误的每个步骤上重新启动工作流程 并希望转到检查这些步骤的最后一步并以失败的方式完成此作业 但我无法获取之前步骤的状态信息 name CI on pull request jobs m
  • 为什么圆圈在碰撞时会振动(画布)

    我一直在创建 agar io 的克隆 但我不明白为什么圆圈相互接触时会开始振动 下面是我的代码 var canvas ctx width innerWidth height innerHeight mouseX 0 mouseY 0 var
  • 您使用什么数据挖掘工具? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • TYPO3:为一个扩展设置多个存储pid

    我构建了一个扩展 它有一个 详细信息 表 其中包含包含内联到另一个对象的标题和描述的详细信息 现在新的详细信息存储在与对象相同的 pid 中 但我想更改它 这个问题 https stackoverflow com questions 151
  • 结合使用filter()和includes()来获得部分匹配

    我有一个包含我想要搜索的对象的数组 可搜索数组如下所示 value 0 label john value 1 label johnny value 2 label peter value 3 label peterson 我使用 Lodas
  • Applicative 之于 monad 就像 X 之于 comonad

    我们能解这个方程的 X 吗 Applicative 之于 monad 就像 X 之于 comonad 想了想 我觉得这其实是一个倒退的问题 有人可能会认为ComonadApply https hackage haskell org pack
  • Electron 中的自定义 HTML 对话框

    如何 或者甚至可能 在 Electron 中使用自定义 HTML 对话框 我知道 Electron 提供了某些对话框 showMessageDialog showErrorDialog 但这些似乎不允许自定义 HTML 我不想使用本机 HT
  • 时间:2019-03-17 标签:c#mvvm将视图绑定到带标题的tabcontrol

    我有一个带有主视图的 wpf 程序 Window 其中包含一个TabControl来展示几个不同的UserControl意见 子视图 每个选项卡中一个 每个视图都有一个关联的视图模型 我希望绑定TabControl这样我只需要加载一个新的s
  • 如何将所有匹配行拉入一个缓冲区?

    如何将所有匹配的行拉入缓冲区 给定一个如下文件 match 1 skip skip match 2 match 3 skip 我希望能够发出一个命令将与模式匹配的所有行 在本例中为 match 提取到单个缓冲区中 以便我可以将其放入另一个文
  • 将Class 添加到 getElementsByClassName 数组

    我需要一点帮助 因为我对 getElementsByClassName 感到沮丧 我有一个 svg 地图 其中包含带有类的路径 我现在需要列出某个类别的所有内容并添加另一个类别 现在我有 var testarray document get
  • Phonegap 2.4 Android Proguard 配置

    我已经将构建从 Phonegap Cordova 2 0 升级到 2 4 并且在开发中一切正常 直到我真正开始测试最终发布的 apk 在浪费了大量时间之后 我发现由于某种原因 现在当我运行构建时 我的 proguard 配置正在以某种方式破
  • 在Python中的嵌套字典中存储目录结构

    我正在尝试将目录结构存储在嵌套字典中 目录树 dirA dirB1 file1 txt dirB2 file2 txt templates base html report html test py 嵌套字典如下 dirs dirs dir
  • ASP.NET 启动 Web 性能分析

    我正在尝试确定 ASP NET 应用程序初始启动时间过长 恕我直言 的原因 该应用程序使用各种第三方库 以及许多我确信可以整合的参考资料 但是 我正在尝试识别 并分配责任 这些 dll 以及它们对扩展启动过程的贡献有多大 到目前为止 启动时
  • 嵌套数组上的 MongoDB $elemMatch 投影

    我有一个这样的集合 摘要 id summaryid locations id loc1 datacenters id dc1 1 clusters id cl1 1 servers
  • 如何在 AngularJS 中从 $http.get 返回图像

    在我的控制器中 我调用一个返回承诺的服务 var onComplete function data scope myImage data 在我的服务中 我通过将 url 直接传递给图像本身来调用以获取图像 return http get h
  • C++ 头文件的解析器可以使用标准 Linux 工具提取函数吗?

    有这样的事吗 我需要从头文件中提取 C 函数及其使用的所有参数 如果我能使用标准的 Linux 程序就好了 您可以使用 Understanding 4 C 这是一个前端工具 可以浏览源代码并为源代码生成指标 它还具有强大的API 允许您编写
  • 更改 Coldfusion 上附件的文件名

    我在用着cfmailparam将文件附加到电子邮件 我正在从数据库中获取文件名和路径 通常 附加文件具有唯一的名称 但我可以通过查询数据库表中的以下列来获取其原始文件名 ASSET FILE NAME 独特的名字 ASSET REAL NA
  • 浮点数学有问题吗?

    考虑以下代码 0 1 0 2 0 3 gt false 0 1 0 2 gt 0 30000000000000004 为什么会出现这些不准确的情况 Binary 浮点 https en wikipedia org wiki Double p