简单的浮点数会失去精度

2023-11-22

我正在使用 Delphi XE2 Update 3。即使是最简单的浮点数也存在精度问题(例如3.7)。给定以下代码(32 位控制台应用程序):

program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses System.SysUtils;

var s: Single; d: Double; x: Extended;
begin
  Write('Size of Single  -----  ');  Writeln(SizeOf(Single));
  Write('Size of Double  -----  ');  Writeln(SizeOf(Double));
  Write('Size of Extended  ---  ');  Writeln(SizeOf(Extended));  Writeln;

  s := 3.7;  d := 3.7;  x := 3.7;

  Write('"s" is ');                  Writeln(s);
  Write('"d" is ');                  Writeln(d);
  Write('"x" is ');                  Writeln(x);                 Writeln;

  Writeln('Single Comparison');
  Write('"s > 3.7"  is  ');          Writeln(s > 3.7);
  Write('"s = 3.7"  is  ');          Writeln(s = 3.7);
  Write('"s < 3.7"  is  ');          Writeln(s < 3.7);           Writeln;

  Writeln('Double Comparison');
  Write('"d > 3.7"  is  ');          Writeln(d > 3.7);
  Write('"d = 3.7"  is  ');          Writeln(d = 3.7);
  Write('"d < 3.7"  is  ');          Writeln(d < 3.7);           Writeln;

  Writeln('Extended Comparison');
  Write('"x > 3.7"  is  ');          Writeln(x > 3.7);
  Write('"x = 3.7"  is  ');          Writeln(x = 3.7);
  Write('"x < 3.7"  is  ');          Writeln(x < 3.7);           Readln;
end.

我得到这个输出:

Size of Single  -----  4
Size of Double  -----  8
Size of Extended  ---  10

"s" is  3.70000004768372E+0000
"d" is  3.70000000000000E+0000
"x" is  3.70000000000000E+0000

Single Comparison
"s > 3.7"  is  TRUE
"s = 3.7"  is  FALSE
"s < 3.7"  is  FALSE

Double Comparison
"d > 3.7"  is  TRUE
"d = 3.7"  is  FALSE
"d < 3.7"  is  FALSE

Extended Comparison
"x > 3.7"  is  FALSE
"x = 3.7"  is  TRUE
"x < 3.7"  is  FALSE

你可以看到extended是唯一正确评估的类型。我认为精度仅在使用复杂的浮点数时才成为问题3.14159265358979323846,不是那么简单3.7。使用时的问题single有点道理。但为什么不double work?


必读:每个计算机科学家都应该了解的浮点运算知识,大卫·戈德堡。

问题不在于精度。相反,问题是代表性问题之一。首先,让我们回顾一下浮点数用于表示实数。实数的数量是无限的。当然,对于整数也可以这样说。但这里的区别在于,在特定范围内,整数的数量是有限的,而实数的数量是无限的。确实如此最初由康托尔展示,任何有限的实数区间都包含不可数的实数值。

So it is clear that we cannot represent all real numbers on a finite machine. So, which numbers can we represent? Well, that depends on the data type. Delphi floating point data types use binary representation. The single (32 bit) and double (64 bit) types adhere to the IEEE-754 standard. The extended (80 bit) type is an Intel specific type. In binary floating point a representable number has the form k2n where k and n are integers. Note that I am not claiming that all numbers of this form are representable. That is not possible because there are an infinite quantity of such numbers. Rather my point is that all representable numbers are of this form.

可表示的二进制浮点数的一些示例包括:1、0.5、0.25、0.75、1.25、0.125、0.375。您的值 3.7 不能表示为二进制浮点值。

就您的代码而言,这意味着它没有执行您期望的操作。您希望与值 3.7 进行比较。但相反,您正在与最接近的精确表示值 3.7 进行比较。作为实现细节的问题,这个最接近的精确可表示值是在扩展精度的情况下的。这就是为什么使用扩展的版本看起来符合您的预期。但是,不要认为这意味着您的变量x等于3.7。事实上,它等于最接近的可表示扩展精度值 3.7。

罗布·肯尼迪的最有用的网站可以向您显示与特定数字最接近的可表示值。在 3.7 的情况下,这些是:



3.7 = + 3.70000 00000 00000 00004 33680 86899 42017 73602 98112 03479 76684 57031 25
3.7 = + 3.70000 00000 00000 17763 56839 40025 04646 77810 66894 53125
3.7 = + 3.70000 00476 83715 82031 25
  

这些按扩展、双、单的顺序呈现。换句话说,这些是变量的值x, d and s分别。

如果您查看这些值,并将它们与最接近的扩展值 3.7 进行比较,您就会明白为什么您的程序会产生这样的输出。这里的单精度值和双精度值都大于扩展值。这就是你的程序告诉你的。

我不想就如何比较浮点值提出任何笼统的建议。做到这一点的最佳方法始终非常关键地取决于具体问题。无法给出有用的笼统建议。

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

简单的浮点数会失去精度 的相关文章

  • Delphi 2005 Web 服务问题

    我在尝试通过 Delphi 访问 Web 服务时遇到问题 我使用了 2007 版 WSDLimp 工具的 java WSDL 看起来它已正确创建了所有对象 然而 当我制作一个调用该服务的测试程序时 每个对象都是空的 如果我在 HTTPRIO
  • 面向 Delphi 开发人员的 Qt

    有人知道为 Delphi C Builder VCL 开发人员解释 Qt 的书籍或教程吗 对于具有该背景的开发人员来说 学习 Qt 的最佳方法是什么 我对如何使用 Qt 完成我知道如何在 Delphi 中完成的事情特别感兴趣 例如 Qt 相
  • Delphi 应用程序被 Google Chrome 视为“危险”

    我经常用Delphi 2009制作数学软件 并将其发布在我的网站上 然而 去年左右 Google Chrome 开始认为我的一小部分 但数量不断增加 EXE 是 有害的 并且 Google Chrome 拒绝下载它们 例如 今天我编写了一个
  • 从不同的形式调用过程

    我正在使用 Lazarus 我有一个名为TForm1单元名称为 Unit 1 在这里我有一个名为mergeDATfile a shortint 这会产生一些东西 顺便说一句 我必须创建另一个名为TForm2里面有按钮 Button1 当它被
  • Firebird 或 NexusDB

    我知道有很多与 Delphi 数据库相关的问题 但我只考虑这两个数据库 我需要查询大约 100 000 条记录 根据您的经验 哪个更快 作为嵌入式 as C S Thanks 我还没用过 Nexus tbh 但我经常使用 Firebird
  • 如何使用 IdTCPClient 等待来自服务器的字符串?

    我的 IdTelnet indy 10 1 有问题 我无法以 Unicode 模式从服务器读取数据 现在我想用 IdTCPClient 编写 telnet 终端 服务器有时发送一行 有时发送越来越多的行 但发送之间没有固定的时间 现在我的问
  • 让线程在窗体关闭时保持运行

    我在我的应用程序上创建了一个同步线程 我想知道如果我关闭申请表 是否有办法让该线程保持打开状态 直到完成同步过程 调用线程的WaitFor方法在您的 DPR 文件中 之后Application Run线 如果线程已经运行完毕 那么WaitF
  • Delphi:如何计算大文件的 SHA 哈希值

    您好 我需要生成 5 Gig 文件的 SHA 您知道有一个非基于字符串的 Delphi 库可以做到这一点吗 你应该使用DCPcrypt v2 http www cityinthesky co uk cryptography html读取缓冲
  • 在 tlistbox 中绘制缩略图

    在 DelphiXE 中 我使用 tFileOpenDialog 选择一个文件夹 然后在 tListBox 中列出该文件夹中的所有 jpg 文件 我允许将列表项拖放到列表中进行自定义排序 以便稍后按顺序显示它们 我希望能够在文件名旁边绘制图
  • Delphi中AsInteger和Value有什么区别?

    我想知道以下两个与delphi中的数据集相关的语句之间的区别 dsMyDataSet ParamByName ID AsInteger 1122 If ID is integer dsMyDataSet ParamByName ID AsS
  • 为什么使用过程来创建对象比使用函数更受欢迎?

    这类似于这个问题 https stackoverflow com questions 1894217 is it memory safe to provide an object as a function result 我问 为什么 到最
  • Delphi 2010 控制闪烁

    我一直在从 XP 操作系统升级或迁移我们的软件 以便能够在 Windows 7 下编译和运行 我们的软件开始出现我们在 Windows XP 下没有注意到的问题 目前 我正在处理 TForm 上闪烁的用户定义控件 它似乎时不时地闪烁 但并非
  • Delphi - 如何将通用参数传递给接受 const 参数数组的函数

    我有一个 基类 其中包含一个 函数 该函数接受 const 数组 类型的参数 如下所示 type TBaseClass class TObject public procedure NotifyAll const AParams array
  • Delphi - 通过 ADO 查询获取 Excel 行

    我有以下 Excel 文件 我将 AdoConnection ConnectionString 设置为 AdoConnection ConnectionString Provider Microsoft Jet OLEDB 4 0 Data
  • 为什么我不能在接收数组参数的函数中使用 SetLength?

    我正在尝试使用以下函数来设置动态数组 即 var 参数 的长度 当我尝试编译代码时只有一个错误 dcc64 错误 lolcode dpr 138 E2008 不兼容类型 function execute var command array
  • 创建FileStream时如何处理异常

    我有一个这样的函数 我想重构它 function Myfunction sUrl sFile String Boolean var GetData TFileStream begin Result False if the line bel
  • ComboBox.Sorted 发生了什么:= True;在德尔福 10.2 中?

    最近我的最后一个问题获得了 风滚草 徽章 我不确定是否应该问更多问题 但这里是 我正在填充一个TComboBox使用 sqlite 表中的项目 效果很好 在我以前的 Delphi 版本中 我能够使用ComboBox1 Sorted True
  • 如何更改 Delphi 2010 IDE 中编辑器选项卡的字体大小?

    有谁知道如何更改 Delphi 2010 IDE 中编辑器选项卡的字体大小 我的 1080p 22 显示器的字体太小 无法阅读 而且会导致眼睛疼痛 一些笔记 它不尊重系统的 DPI 设置 因此更改系统设置没有帮助 而且 我现在已经使用 14
  • delphi定时器比定时器服务中断例程更快

    大家好 我被要求为某人维护一个基于 Delphi 5 的程序 该程序使用一个计时器对象每 50 毫秒计时一次 并且在每次计时结束时运行单线程代码块 我只是想知道 如果执行这段代码所花费的时间比计时器滴答间隔长 会发生什么 这会很糟糕吗 例如
  • 如何添加资源并使用它们

    在我的应用程序中 我想添加 2 个图像作为资源 我想使用这些图像 当我在应用程序中单击 是 按钮时 第一张图像将被设置为壁纸 当我在应用程序中单击 否 按钮时 第二张图像将被设置为桌面壁纸 提前致谢 regards 最简单的方法是创建一个文

随机推荐

  • C++ 引用与返回值

    我理解引用的原则是避免复制大型结构 但是如果您正在编写的函数本身创建了大型结构怎么办 与将目标对象作为引用传递并从函数内部填充相比 在本地创建变量然后返回它是否效率较低 或者更有可能耗尽内存 我似乎无法很好地表达 所以一个具体的例子 假设一
  • JS 对象键带引号还是不带引号? [复制]

    这个问题在这里已经有答案了 可能的重复 带引号和不带引号的对象键有什么区别 感兴趣吗 什么是正确的方法 是否将对象键写在引号中 那是 var obj name Jhon or var obj name Jhon 例如 从 php 代码ech
  • Git 中的 HEAD 和 ORIG_HEAD

    这些符号代表什么以及它们的含义是什么 我在官方文档中找不到任何解释 HEAD是 直接或间接 即符号 对当前提交的引用 这是您已在工作目录中签入的提交 除非您进行了一些更改或同等更改 并且是在 git commit 之上创建新提交的提交 通常
  • 无法在具有 @objc 属性的协议中使用自定义类?

    我正在尝试创建一个用于 JSON 加载委托的协议 JSONLoaderDelegate 我的另一堂课叫做JSONLoader 应该将事件分派给它的委托 实现JSONLoaderDelegate协议 如 self delegate jsonL
  • Laravel 8 - 找不到驱动程序:Illuminate\Database\QueryException 无法找到驱动程序(SQL:从 `list` 中选择 *)

    我已经在我的 Linux Mint 20 上安装了 Laravel 8 作为我的个人实验 所以我对 Laravel 的新版本很陌生 我搜索了许多来源如何使用 CRUD 方法显示表 以便该表显示在网络中 其中包含来自 MySQL 数据库的数据
  • Spring data JPA:在结果元组中找不到别名!执行自定义查询时出错

    我正在尝试使用 mysql 数据库执行自定义查询 Queryspring data jpa 的注解 该表是 Field Type Null Key Default Extra id decimal 10 0 NO PRI NULL firs
  • iOS中如何实现弹出对话框?

    计算后 我想显示一个弹出窗口或警报框 向用户传达消息 有谁知道我在哪里可以找到有关此的更多信息 Yup a UIAlertView可能就是您正在寻找的 这是一个例子 UIAlertView alert UIAlertView alloc i
  • std::bind 创建的函子住在哪里?

    函数指针可以指向自由函数 函数对象 成员函数调用的包装器等任何内容 但是 std bind 创建的函子可以有状态 也可以有自定义创建的函子 该状态分配在哪里 谁在删除它 考虑下面的例子 当向量被删除时 状态 数字10 会被删除吗 谁知道在函
  • 计算GPS坐标以形成给定大小的半径

    我想出了一种方法 它接受坐标和范围 以英里为单位 并返回围绕原点形成圆圈的坐标列表 我似乎已经取得了一些进展 但我在降低范围部分方面遇到了问题 private const Double LAT MILE 0 0144839 private
  • 仅使用 XAML 在左键单击时显示上下文菜单

    WPF 的默认行为ContextMenu是当用户右键单击时显示它 我想要ContextMenu当用户单击鼠标左键时显示 看起来这应该是一个简单的属性ContextMenu 但事实并非如此 我操纵了它 这样我就可以处理LeftMouseBut
  • 为什么匿名函数表达式和命名函数表达式的初始化如此不同?

    我正在看第13条或 ECMAScript 规范 v 5 匿名函数表达式的初始化如下 返回按照 13 2 中的规定创建新 Function 对象的结果 其参数由 FormalParameterListopt 指定 主体由 FunctionBo
  • 作曲家自动加载

    我目前正在尝试将 PSR 0 自动加载与 Composer 结合使用 但出现以下错误 Fatal error Class Twitter Twitter not found 我的目录结构如下 Project src Twitter Twit
  • 如何将多处理与请求模块一起使用?

    我是 python 的新开发者 我的代码是下面的代码 import warnings import requests import multiprocessing from colorama import init init autores
  • 为什么我需要在 g++ 中使用 typedef typename 而不是 VS?

    自从 GCC 发现我有这个问题以来已经有一段时间了 但它今天才发生 但我一直不明白为什么 GCC 需要在模板中使用 typedef typename 而 VS 和我猜 ICC 不需要 typedef typename 是一个 bug 还是一
  • 如何将图像作为资源包含在 C++ 可执行文件中?

    是否可以将图像 jpegs 作为资源包含在 win32 c 可执行文件中 如果是这样怎么办 如果仅是 Windows 则使用自定义资源 如果您想要跨平台的东西 那么请执行我为最近的项目所做的操作 创建一个将 JPEG 编码为char buf
  • Capybara 与 jquery.selectize 的集成测试

    如何使用表单编写水豚集成测试jquery selectize 我想测试用户输入几个值 这里的大多数答案都从底层改变了内容 并且与用户交互不同 这是一个接近用户所做操作的版本 waits for the text to show up in
  • Google App Engine 应用程序实例回收和响应时间

    我在 GAE for Java 小组上发布了这篇文章 但我希望在这里更快地得到一些答案 我决定对我的应用程序进行一些长期运行的性能测试 我 每 5 30 分钟创建一些小型客户端点击应用程序 我运行 3 5 与此类客户端的线程数 我注意到响应
  • NodeJS - 设置mean.io找不到模块错误

    我对整个 node js 事物有点陌生 当尝试安装 MEAN 包时http mean io 我忠实地遵循了以下步骤 我 cd 到我的目录 运行 npm install 然后运行 grunt 命令 并收到此错误 Error Cannot fi
  • 如何解码 HTML 实体

    我有带有 HTML 实体的字符串变量 var str Some text x26 text 我想将其转换 解码 为原始字符 Some text text JavaScript 没有内置函数来实现想要的结果 我无法使用 jQuery 或 DO
  • 简单的浮点数会失去精度

    我正在使用 Delphi XE2 Update 3 即使是最简单的浮点数也存在精度问题 例如3 7 给定以下代码 32 位控制台应用程序 program Project1 APPTYPE CONSOLE R res uses System