为什么 MATLAB 中的 24.0000 不等于 24.0000?

2023-11-25

我正在编写一个程序,需要删除存储在矩阵中的重复点。问题是,当检查这些点是否在矩阵中时,MATLAB 无法识别矩阵中的它们,尽管它们存在。

在下面的代码中,intersections函数获取交点:

[points(:,1), points(:,2)] = intersections(...
    obj.modifiedVGVertices(1,:), obj.modifiedVGVertices(2,:), ...
    [vertex1(1) vertex2(1)], [vertex1(2) vertex2(2)]);

结果:

>> points
points =
   12.0000   15.0000
   33.0000   24.0000
   33.0000   24.0000

>> vertex1
vertex1 =
    12
    15

>> vertex2    
vertex2 =
    33
    24

两点(vertex1 and vertex2) 应从结果中消除。它应该通过以下命令完成:

points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :);
points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);

这样做之后,我们得到了意想不到的结果:

>> points
points =
   33.0000   24.0000

结果应该是一个空矩阵。正如你所看到的,第一对(或第二对?)[33.0000 24.0000]已经被淘汰了,但第二个还没有被淘汰。

然后我检查了这两个表达式:

>> points(1) ~= vertex2(1)
ans =
     0
>> points(2) ~= vertex2(2)
ans =
     1   % <-- It means 24.0000 is not equal to 24.0000?

问题是什么?


更令人惊讶的是,我制作了一个仅包含以下命令的新脚本:

points = [12.0000   15.0000
          33.0000   24.0000
          33.0000   24.0000];

vertex1 = [12 ;  15];
vertex2 = [33 ;  24];

points = points((points(:,1) ~= vertex1(1)) | (points(:,2) ~= vertex1(2)), :);
points = points((points(:,1) ~= vertex2(1)) | (points(:,2) ~= vertex2(2)), :);

结果如预期:

>> points
points =  
   Empty matrix: 0-by-2

您遇到的问题与如何浮点数字都在计算机上表示。关于浮点表示的更详细讨论出现在我的答案的末尾(“浮点表示”部分)。这TL;DR版本:由于计算机的内存量有限,因此数字只能以有限的精度表示。因此,浮点数的精度被限制在一定数量的小数位(对于浮点数来说大约是16位有效数字)双精度值,MATLAB 中使用的默认值)。

实际精度与显示精度

现在解决问题中的具体示例......while 24.0000 and 24.0000 are 显示的以同样的方式,事实证明,在这种情况下,它们实际上相差非常小的小数。您看不到它是因为 MATLAB默认只显示4位有效数字,保持整体陈列整洁。如果您想查看完整的精度,您应该发出format long命令或查看十六进制表示号码:

>> pi
ans =
    3.1416
>> format long
>> pi
ans =
   3.141592653589793
>> num2hex(pi)
ans =
400921fb54442d18

初始化值与计算值

由于浮点数只能表示有限数量的值,因此计算结果可能会落在这两个表示形式之间。在这种情况下,结果必须四舍五入为其中之一。这就介绍了一个小机器精度误差。这也意味着直接初始化值或通过某些计算初始化值可能会给出略有不同的结果。例如,值0.1没有exact浮点表示(即,它会稍微四舍五入),因此由于舍入误差累积的方式,您最终会得到这样的反直觉结果:

>> a=sum([0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]);  % Sum 10 0.1s
>> b=1;                                               % Initialize to 1
>> a == b
ans =
  logical
   0                % They are unequal!
>> num2hex(a)       % Let's check their hex representation to confirm
ans =
3fefffffffffffff
>> num2hex(b)
ans =
3ff0000000000000

如何正确处理浮点比较

由于浮点值可能相差非常小,因此任何比较都应该通过检查这些值是否在彼此的某个范围(即容差)内来完成,而不是彼此完全相等。例如:

a = 24;
b = 24.000001;
tolerance = 0.001;
if abs(a-b) < tolerance, disp('Equal!'); end

将显示“等于!”。

然后您可以将代码更改为:

points = points((abs(points(:,1)-vertex1(1)) > tolerance) | ...
                (abs(points(:,2)-vertex1(2)) > tolerance),:)

浮点表示

对浮点数(特别是浮点运算的 IEEE 754 标准) is 每个计算机科学家都应该了解的浮点运算知识作者:大卫·戈德堡。

二进制浮点数实际上由三个整数表示:一个符号位s, 有效数(或系数/分数)b,和一个指数e. 对于双精度浮点格式,每个数字由在内存中排列的 64 位表示,如下所示:

enter image description here

然后可以通过以下公式找到实际值:

enter image description here

此格式允许 10^-308 到 10^308 范围内的数字表示。对于 MATLAB,您可以从以下位置获取这些限制realmin and realmax:

>> realmin
ans =
    2.225073858507201e-308
>> realmax
ans =
    1.797693134862316e+308

由于用于表示浮点数的位数是有限的,因此在上述给定范围内只能表示有限的数字。计算通常会产生与这些有限表示之一不完全匹配的值,因此必须对这些值进行四舍五入。这些机器精度误差正如上面的例子中所讨论的那样,它们以不同的方式变得明显。

为了更好地理解这些舍入误差,查看函数提供的相对浮点精度很有用eps,它量化从给定数字到下一个最大浮点表示形式的距离:

>> eps(1)
ans =
     2.220446049250313e-16
>> eps(1000)
ans =
     1.136868377216160e-13

请注意,精度是relative所表示的给定数字的大小;较大的数字在浮点表示之间的距离较大,因此小数点后的精度位数较少。对于某些计算来说,这可能是一个重要的考虑因素。考虑以下示例:

>> format long              % Display full precision
>> x = rand(1, 10);         % Get 10 random values between 0 and 1
>> a = mean(x)              % Take the mean
a =
   0.587307428244141
>> b = mean(x+10000)-10000  % Take the mean at a different scale, then shift back
b =
   0.587307428244458

请注意,当我们改变值时x从范围[0 1]到范围[10000 10001],计算平均值,然后减去平均值偏移进行比较,我们得到最后 3 位有效数字不同的值。这说明了数据的偏移或缩放如何改变对其执行的计算的准确性,这是某些问题必须考虑的问题。

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

为什么 MATLAB 中的 24.0000 不等于 24.0000? 的相关文章

  • 浮点除以零的行为

    Consider include
  • 在 numpy/scipy 中查找 matlab 函数

    是否有一个等价的函数find A gt 9 1 来自 numpy scipy 的 matlab 我知道有nonzeronumpy 中的函数 但我需要的是第一个索引 以便我可以在另一个提取的列中使用第一个索引 Ex A 1 2 3 9 6 4
  • 如何调整x轴和y轴的大小

    如何调整 x 轴和 y 轴的大小 我想要什么 更具体 3900 60 30 0 60 120 180 3600 我做了什么 a 0 0 1 10000 plot a 我应该写什么才能按预期调整 x 和 y 轴的大小 EDIT 我不想 390
  • 了解 Matlab 中的 DEL2 函数以便用 C++ 对其进行编码

    为了用 C 编写 DEL2 matlab 函数 我需要了解该算法 我已经成功地为不在边界或边缘上的矩阵元素编写了函数 我已经看过几个有关它的主题 并通过输入 edit del2 或 type del2 来阅读 MATLAB 代码 但我不明白
  • 静态时序数据的数据库解决方案

    我们拥有一个庞大且不断增长的实验数据集 该数据集取自约 30 000 名受试者 对于每个主题 都有多个数据记录 在每个记录中 收集了多个生理数据时间序列 每个时间序列约 90 秒长 并以 250Hz 采样 我应该注意到 时间序列的任何给定实
  • 如何在 MATLAB 中为 4 个子图创建一个通用图例?

    如何在 MATLAB 中为 4 个子图创建一个通用图例 如下所示 又快又脏 hSub subplot 3 1 1 plot 1 1 1 1 1 1 1 1 hLegend legend hello i am legend subplot 3
  • 为什么“dtoa.c”包含这么多代码?

    我将是第一个承认我对低级编程的整体知识有点稀疏的人 我理解许多核心概念 但我不经常使用它们 话虽这么说 我对需要多少代码感到非常惊讶dtoa c http www netlib org fp dtoa c 在过去的几个月里 我一直致力于用
  • java - IBM-IEEE 双精度浮点字节转换

    我需要在 Java 中对字节数组进行 IBM IEEE 浮点转换 我能够使用成功地进行单精度浮点字节的转换http www thecodingforums com threads c code for converting ibm 370
  • 如何解决 boost::multi precision::cpp_dec_float 除法错误

    除以boost multiprecision cpp dec float有某种舍入误差 如下 include
  • 覆盖 MATLAB 默认静态 javaclasspath 的最佳方法

    MATLAB 配置为在搜索用户可修改的动态路径之前搜索其静态 java 类路径 不幸的是 静态路径包含相当多非常旧的公共库 因此如果您尝试使用新版本 您可能最终会加载错误的实现并出现错误 例如 静态路径包含 google collectio
  • 有没有办法在 MATLAB 中查看 pcode 文件 (.p) 的源代码?

    有没有办法在 MATLAB 中打开 pcode 文件 p 如果 开放 是指edit 那么当然不是 pcode 中的 p 代表 受保护 其主要设计目标是在保护其源代码的同时部署功能组件 如果 开放 是指run 那么当然是的 引用手册 http
  • ODE 时间 Matlab 与 R

    如果在 matlab 中使用可变时间步长求解器 例如 ODE45 我会定义输出的时间跨度 即times 0 50 matlab 将返回 0 到 50 之间不同时间步长的结果 然而在 R 中 我似乎必须定义我希望 ODE 返回结果的时间点 即
  • 在c#中打印0.1的增量

    我目前正在阅读 Steve McConnell 的 Code Complete 特别是第 295 页有关浮点数的内容 当我运行以下代码时 double nominal 1 0 double sum 0 0 for int i 0 i lt
  • 在 Matlab 中保存当前运行的脚本

    有没有办法保存Matlab中当前运行的脚本 我有一个脚本 它会自动备份一组脚本 但如果我更改了当前脚本 则保存的版本将过期 也许可以调用一些java Thanks 在 Yair Altman 网站上的某个地方 请参阅我的其他答案中的链接 他
  • 如何在 MATLAB 中可视化球体的交集?

    似乎这个问题在一些地方被问过 包括SO https stackoverflow com questions 35130336 draws the intersecting volume of two spheres in matlab 我最
  • 将 .NET 小数存储到 MySQL 中的最佳字段定义是什么?

    我需要将小数存储到 MySQL 中 它可以具有不同的精度 因此我很想知道哪种 MySQL 字段类型绝对等同于 NET 的字段类型decimal http msdn microsoft com en us library system dec
  • matlab mex 文件和 C++ dll (Windows)

    我有一个带有 Test 类的 DLL 标题 class MY EXPORT Test public int doit const string str 和来源 int Test doit const string str return in
  • 在 MATLAB 中使用 FFT 的频率响应

    这是场景 使用频谱分析仪 我有输入值和输出值 样本数是32000采样率为2000样本 秒 输入是正弦波50 hz 输入为电流 输出为压力 单位 psi 我如何使用 MATLAB 根据这些数据计算频率响应 使用 MATLAB 中的 FFT 函
  • Matlab:如何显示数组的“真实”值?

    我有一个在脚本中计算的向量 计算后 我将值显示到命令窗口 显示如下 finalResults 1 0e 05 0 0001 0 0 0005 0 0002 0 0001 0 0027 0 0033 0 0001 0 0000 0 0000
  • 检查Matlab中脚本需要使用的函数

    我有一个别人写的代码包 我正在运行一个脚本 它调用一些函数 这些函数又调用更多函数 等等 我想获取不是 MATLAB 内置函数但属于包的一部分的函数列表 我尝试使用matlab codetools requiredFilesAndProdu

随机推荐

  • WCF 中基于令牌的身份验证

    我正在创建一个网站 其中包含 ASP NET 页面和 Flash 小程序 我想将我的业务逻辑封装在 WCF 服务中 该服务将通过两个端点公开 一个端点可通过 HTTP S 通过 Internet 访问 供 Flash 客户端使用 另一个端点
  • 如何在C中迭代unicode字符并使用printf将它们打印在屏幕上?

    我想迭代所有 至少 16 位 unicode 字符并用 C 将它们打印在屏幕上 我知道有相关问题 但他们没有解决问题printf在C中 但这就是我想要实现的目标 如果可能的话 我认为也许用我不知道的技巧应该是可能的 因为我想使用 print
  • 将 Android studio 更新到 3.1.2 后,我收到“无法加载 AppCompat ActionBar,出现未知错误。”

    我尝试在 stackoverflow 上查找其他类似的问题 他们建议我们更改 buildToolsVersion 的版本 但我在我的 gradle 文件中没有看到这样的单词 我的 Gradle 文件 项目 buildscript repos
  • python re.search 错误 TypeError: 预期的字符串或缓冲区

    为什么会 re search docx os listdir os getcwd 产生以下错误 类型错误 预期的字符串或缓冲区 Because os listdir返回一个list but re search想要一个字符串 做你正在做的事情
  • 为什么两个单独创建的不可变对象具有相同的 id,而可变对象具有不同的 id,但两者都引用相同的值? [复制]

    这个问题在这里已经有答案了 两个单独创建的可变列表具有不同的 id Python SHELL 可变 gt gt gt mylist spam eggs gt gt gt yourlist spam eggs gt gt gt id myli
  • Vim 替换期间增量搜索

    我不擅长写 vim 正则表达式 每当我编写一个程序来进行替换时 第一次都不会起作用 因为我最终不可避免地会编写一些 Perl 而不是 vim 的东西 当进行简单搜索时 我的表现要好得多 因为我有incsearch打开后我可以实时查看我的模式
  • 在c#中检测wifi连接

    我正在开发一个 asp net 或 winforms 应用程序 该应用程序应该检测 wifi 连接和强度 目的是为现场代理提供一个指示 表明他们可以连接到我们的总部 我需要什么来检测 wifi 连接 在 ASP NET 中无法做到这一点 A
  • 将 NodeList 转换为数组

    我很难转换NodeList到 IE 8 中的数组 以下内容在 Chrome 中完美运行 但在 IE 8 中toArray 不被认为是有效的 NodeList prototype toArray function var a for var
  • AWSGlue AccessDeniedException,状态代码 400

    我正在尝试为数据工程项目构建数据管道 在S3 Glue Athena等的帮助下 我在设置胶水爬虫以对数据进行索引时陷入困境 即使我根据需要设置了角色 但仍然出现以下错误 service AWSGlue statusCode 400 erro
  • 为什么“rgb (224, 226, 213)”是无效的属性值?

    为什么任何浏览器都不能应用此颜色 RGB 规则 HTML
  • Instagram 位置/搜索端点不支持分页,这是否正确?

    我读过几篇关于 Instagram API 一次仅返回 20 个结果的帖子 在很多情况下 人们建议您只需使用分页信息中返回的下一个 URL 即可 我对此没意见 但是返回的 JSON https api instagram com v1 lo
  • 如何查找R包中的所有函数?

    查找包中关联的所有函数的最佳方法是什么 我目前正在浏览 caTools 包 如果我做 caTools or caTools我只是要搜索调用该函数的函数 而不是包中的函数 有没有一种简单的方法可以访问 R gui 中的所有功能 有什么好的方法
  • 集合 <__NSArrayM: 0x76c11b0> 在枚举时发生了变化

    我对 obj c 比较陌生 所以我一定错过了一些东西 但是当敌人与墙壁碰撞时我的程序崩溃了 我已经找到了将敌人从循环中移除的位置 而在循环中 但对于我的一生 我不知道如何解决它 我的代码如下 错误是 allEnemies removeObj
  • getChildView 没有被调用

    我正在制作一个包含自定义 ExpandableListView 适配器的菜单 尽管尝试将我的代码与 API 示例和我在网上看到的任何其他示例 包括多个密切相关的 SO 问题 进行匹配 但我仍然无法使其工作 我知道正在使用适配器 因为正在显示
  • 如何防止rawproto文件生成或自动删除它们?

    Android gradle 插件生成大量 rawproto文件在build android profile目录 它们有什么用 有没有办法阻止这种疯狂或自动删除它们 我已经被它困扰了很长一段时间 现在我注意到有 GB 的内存占用了我小小的
  • 获取 java.rmi.UnmarshalException:无法识别的方法哈希:远程对象不支持方法

    我是 RMI 技术的新手 当我运行 rmi 客户端程序时 出现异常 java rmi UnmarshalException 无法识别的方法哈希 远程对象不支持方法 我使用的是jdk1 5 远程方法的参数是序列化对象 这些是服务器代码 这是远
  • javascript 音频加载

    我做了一个 javascript 音频测试 所有函数都可以在 Opera FF 和 Chrome 中使用 除了 audio oncanplaythrough 和 audio onend 这两个函数在 Chrome 上不起作用 a href
  • Android 设备有唯一的 ID 吗?

    Android 设备是否有唯一的 ID 如果有 使用 Java 访问它的简单方法是什么 Settings Secure ANDROID ID返回 Android ID 作为每个用户都是唯一的64 位十六进制字符串 import androi
  • 重命名多个匹配模式的目录

    我想重命名 basedir 下与名称匹配的所有目录 例如 In basedir 我有 foo bar blah my bar foo some bar foo1 other foo bar 我想重命名所有匹配的目录bar 但我想保留前缀部分
  • 为什么 MATLAB 中的 24.0000 不等于 24.0000?

    我正在编写一个程序 需要删除存储在矩阵中的重复点 问题是 当检查这些点是否在矩阵中时 MATLAB 无法识别矩阵中的它们 尽管它们存在 在下面的代码中 intersections函数获取交点 points 1 points 2 inters