【问题标题】:Why does (float.MaxValue / float.MinValue) evaluate to Infinity?为什么 (float.MaxValue / float.MinValue) 评估为无穷大?
【发布时间】:2022-01-25 21:11:08
【问题描述】:

考虑以下代码和结果:

double min = (double) float.MinValue;
double max = (double) float.MaxValue;
double epsilon = (double) float.Epsilon;

double range = max - min;
double delta = range / epsilon;

Console.WriteLine ($@"Min: [{min}].");
Console.WriteLine ($@"Max: [{max}].");
Console.WriteLine ($@"Epsilon: [{epsilon}].");
Console.WriteLine ($@"Range: [{range}].");
Console.WriteLine ($@"Delta: [{delta}].");

// Results:
//  Min: [-3.4028234663852886E+38].
//  Max: [3.4028234663852886E+38].
//  Epsilon: [1.401298464324817E-45].
//  Range: [6.805646932770577E+38].
//  Delta: [4.8566719410840996E+83].

我正在尝试一些微积分,试图尽可能接近Zero (0),但令我惊讶的是我以前从未考虑过表示数字类型的范围。

如何表示数字类型的范围?在上面的例子中,我们使用Double 来表示Single 范围。对于Int32,我们可以使用Int64等。

  • 我们如何表示Int64DoubleDecimal 等的范围?
  • 为什么(float.MaxValue / float.Epsilon) 的计算结果为无穷大?它不应该评估为非常接近但小于float.MaxValue 的数字吗?

【问题讨论】:

  • float.MaxValue 约为 3e38,float.Epsilon 约为 1e-45。第一个除以第二个大约是 3e83,远远超过 3e38,不是吗?
  • @Sweeper:你是对的。我试图计算在float.MinValuefloat.MaxValue 范围之间我可以做的最小增量。我没有意识到除法不会透露将发生的迭代次数。
  • 通过doubles 中的计算,您已经可以看到更准确的结果。那是你的Delta 输出:4.8566719410840996E+83。这是一个比float.MaxValue 大得多的数字,因此它会导致无穷大。
  • 正如 Hans Passant 的链接所暗示的,没有单一的“我可以在 float.MinValue 和 float.MaxValue 的范围之间做的最小可能增量”。相反,您可以做的最小可能增量是您要增加的数字的函数。你可能想要实现类似this

标签: c# .net types range numeric


【解决方案1】:

任何编程语言中的数字类型都是数学概念的近似值。由于这些概念包含无穷大,因此无法在真实计算机中准确表示。

  • 范围(定义为类型的最大值和最小值之间的差异)只能由具有更大范围的类型表示。例如,您可以使用decimalSystem.Numerics.BigInteger 来表示Int64 的范围。 BigInteger 也可以用来表示floatdouble 的范围,或者至少是它的整数部分。

  • float.MaxValue / float.Epsilonfloat.Epsilon 是小于一的正数 (public const float Epsilon = 1.401298E-45;)。如果将正数除以小于一的正数,则结果大于该数。例如,10 / 0.5 = 20。但由于您无法在 float 中存储大于 float.MaxValue 的浮点数,因此 Microsoft 决定将其分配为 Single.PositiveInfinity。他们也可以决定结果应该是Single.NaN(不是数字)、Single.MaxValue,甚至是抛出异常。但这就是它的实施方式。 Single 类型(C# 中的float)符合二进制浮点运算的 IEC 60559:1989 (IEEE 754) 标准。

【讨论】:

  • 谢谢。我没有意识到除法会产生一个大于float.MaxValue 可以容纳的值。也许是因为这是我第一次探索表示范围。
猜你喜欢
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2018-12-03
  • 2022-01-23
  • 2014-05-19
  • 2019-05-24
相关资源
最近更新 更多