【问题标题】:Float epsilon is different in c++ than c#c++ 中的浮点 epsilon 与 c# 不同
【发布时间】:2021-10-16 13:57:12
【问题描述】:

这么小问题,出于性能原因,我一直在考虑将我的 C# 代码的一部分转移到 C++。 现在,当我在 C# 中查看我的 float.Epsilon 时,它的值与我的 C++ 值不同。

在 C# 中,如 by microsoft 所述,值为 1.401298E-45。

在 C++ 中,如 by cppreferences 所述,值为 1.19209e-07;

浮点数/单数的最小可能值如何在这些语言之间有所不同?

如果我是正确的,二进制值在字节数方面应该相等,甚至可能是它们的二进制值。还是我看错了?

希望有人能帮助我,谢谢!

【问题讨论】:

  • epsilon 的定义不同。在 C# 中,ist 是 0 和下一个值之间的差值,而在 C++ 中,它是 1 和下一个值之间的差值。
  • Microsoft 页面上充斥着关于浮点的不良陈述。避免使用其中的信息。一些问题: (a) “零和一半的 Epsilon 值被认为是相等的”:Float 中不能有一半的 Epsilon 值;它是不可代表的。 (b) “格式由一个符号、一个 23 位尾数或有效位组成……”:有效位是 24 位,尽管在一个字段中存储为 23 位,根据指数字段存储为 1 位。
  • (c) “机器ε,表示舍入导致的相对误差的上界……”:可以作为单次操作误差的衡量标准,说的不太对上限或它是相对误差。使用四舍五入法,实际上限是 ULP 的 ½,而真正的相对误差有点复杂,因为它会随着 binade 的变化而变化。
  • (d)“右边的常数只精确到指定的数字”:两个值具有相同的精度;右边的那个是不准确的⅓。微软关于精度的声明是bad
  • (e) “如果您创建一个自定义算法来确定两个浮点数是否可以被视为相等,您必须使用一个大于 Epsilon 常数的值来确定可接受的绝对余量两个值的差异被视为相等。”:There is no general solution for comparing floating-point numbers;每个应用程序都必须同时处理误报和误报,这可能对其具体情况有所不同。因此,“您必须使用大于 Epsilon 常数的值”是不正确的。

标签: c# c++ floating-point epsilon


【解决方案1】:

您引用的第二个值是 IEEE binary32 值的 machine epsilon

您引用的第一个值是 NOT 机器 epsilon。从您链接的文档中:

Epsilon 属性的值不等价于机器 epsilon,它表示浮点运算中由于舍入导致的相对误差的上限。

来自wiki Variant Definitions section for machine epsilon

IEEE 标准没有定义术语机器 epsilon 和单位舍入,因此使用了这些术语的不同定义,这可能会引起一些混淆。

...

以下不同的定义在学术界之外更为普遍:机器 epsilon 被定义为 1 和下一个更大的浮点数之间的差。

C# 文档正在使用该变体定义。

所以答案是您正在比较两种不同类型的 Epsilon。

【讨论】:

  • 另外请注意,您可以在 C++ 中使用 std::numeric_limits<float>::denorm_min() 来获取 C# 的 float.Epsilon
【解决方案2】:

C++

返回机器 epsilon,即 1.0 与浮点类型 T 可表示的下一个值之间的差。 https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon

C#

表示大于零的最小正单值。该字段是恒定的。 https://docs.microsoft.com/en-us/dotnet/api/system.single.epsilon?view=net-5.0

结论

C# 的下一个值从 0 开始,C++ 的下一个值从 1 开始。两个完全不同的东西。

编辑:另一个答案可能更正确

【讨论】:

    【解决方案3】:

    从您引用的链接中,如果您想要类似于 .NET Single.Epsilon(“大于零的最小正单值”)的值,则应使用值 FLT_TRUE_MIN(“float 的最小正值”)。

    【讨论】:

      猜你喜欢
      • 2021-10-27
      • 2012-06-24
      • 2010-09-12
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2022-12-31
      • 2012-04-29
      • 1970-01-01
      相关资源
      最近更新 更多