【问题标题】:How to safely compare std::complex<double> with Zero with some precision Epsilon?如何安全地将 std::complex<double> 与零与一些精度 Epsilon 进行比较?
【发布时间】:2022-01-02 01:49:32
【问题描述】:

我需要安全地检查我的复数是否为零(或非常相似)。如何处理浮点数?

我可以使用类似的东西吗:

std::complex<double> a;
if(std::abs(std::real(a)) <= std::numerical_limits<double>::epsilon() && std::abs(std::imag(a)) <= std::numerical_limits<double>::epsilon())
{
//...
}

我将值除以 a 并且不想得到 INF 作为结果。

【问题讨论】:

  • en.cppreference.com/w/cpp/types/numeric_limits/epsilon 返回机器epsilon,即1.0与浮点类型T可表示的下一个值的差值。见cppreference中的例子,当你增加时,浮点数变得不那么密集数字的大小,您需要考虑缩放
  • std::abs(a) &lt; epsilon 会不会比只比较真实的部分更好?
  • 这将使“足够接近”的区域变成正方形; a + ai 形式的数字将比a + 0i0 + ai 更远离实际零“零”。一个圆圈,即abs(a) 的大小,不是更好吗?
  • "检查我的复数是否为零" --> x == 0.0 就足够了。以线性方式与 epsilon 进行比较,将浮点数从浮点数中取出。发布真实用例以获得更多反馈。
  • ... 此外,任何与零比较的“捏造”都会以假阴性换成假阳性,反之亦然,这些风险和回报取决于应用程序。因此,对此没有一般性的答案。而且你没有给出任何上下文,根本没有,没有说明正在执行什么计算或使用什么数据。所以你的问题没有答案。

标签: c++ floating-point comparison similarity complex-numbers


【解决方案1】:

你试过从&lt;cmath&gt;std::fpclassify吗?

if (std::fpclassify(a.real()) == FP_ZERO) {}

检查复数的实部和虚部是否都为0:

if (a == 0.0) {}

正如@eerorika 早在我之前提到的那样。您拒绝的答案。
浮点精度、舍入、升旗、次正规都是实现定义的(参见:[basic.fundamental][support.limits.general]ISO C 5.2.4.2.2)。

【讨论】:

  • 这个功能是如何工作的?为什么我们只检查数字的实部。除法 RealNumber/ImaginaryNumber 或 ImaginaryNumber/OtherImaginaryNumber 是否被禁止?
  • 我没有考虑这一切。复数论在我的脑海中并不是很新鲜。我不确定,但如果虚部是 0:它不只是一个实数吗? ?
  • “它不只是一个实数吗”——是的,在这种情况下,如果实数部分也为零,我们会得到一个错误。但我询问了实部为零而虚部不是的情况。
【解决方案2】:

我需要检查我的复数是否为零。如何处理浮点数?

您可以将其与值为 0 的浮点文字进行比较。您不能将整数文字与 std::complex&lt;double&gt; 一起使用。示例:

a == 0.0

我可以使用类似...的东西吗?

你所展示的并没有比较复数是否零;它比较复数是否接近零。这可能是一个合理的操作,例如,如果数字是具有已知误差范围的计算结果,并且您想知道结果是否在误差范围内。但这是一个单独的操作

如果数字接近于零,这是否是比较的好方法取决于用例。比如epsilon不一定是“近”的最佳阈值。您可能会考虑的另一件事是您是否应该将std::abs(a) 与阈值进行比较,而不是分别比较组件,即是否应该使用欧几里得距离而不是曼哈顿距离。

【讨论】:

  • 好奇:为什么“你不能使用整数文字”? complex op int 无效?
  • @chux-ReinstateMonica 例如,如果您使用 std::complex&lt;int&gt;,则可以使用整数文字,但 OP 使用 std::complex&lt;double&gt;
  • 有趣。 LSNED
  • "您所显示的不是比较复数是否为零;它比较的是复数是否接近零。" -- 这是唯一一种比较浮点数的方法。浮点数完全为零是不可能比较的
  • @Robotex 这不是真的。我展示的是可能的,它确实比较了浮点数是否正好为零。
猜你喜欢
  • 2012-11-21
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多