Home > Back-end >  Why does (float.MaxValue / float.MinValue) evaluate to Infinity?
Why does (float.MaxValue / float.MinValue) evaluate to Infinity?

Time:12-26

Consider the following code and results:

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].

I was trying out some calculus, trying to get as close to Zero (0) as possible, and was surprised that I never thought about representing a numeric type's range before.

How would one represent a numeric type's range? In the case above, we're using Double to represent Single ranges. For Int32, we could use Int64, etc.

  • How would we represent ranges for Int64, Double, and Decimal, etc.?
  • Why does (float.MaxValue / float.Epsilon) evaluate to Infinity? Should it not evaluate to a number very close to, but less than float.MaxValue?

CodePudding user response:

The numeric types in any programming language are approximations of mathematical concepts. Since these concepts include infinities, they cannot be represented accurately in real computers.

  • The range (defined as difference between the maximum and minimum value of a type) can only be represented by a type having a lager range. E.g., you could use decimal or System.Numerics.BigInteger to represent the range of Int64. BigInteger could also be used to represent the range of float and double or at least the integer part of it.

  • float.MaxValue / float.Epsilon: float.Epsilon is a positive number smaller than one (public const float Epsilon = 1.401298E-45;). If you divide a positive number by a positive number smaller than one, the result is lager than this number. E.g., 10 / 0.5 = 20. But since you cannot store a float bigger than float.MaxValue in a float, Microsoft decided to assign it Single.PositiveInfinity instead. They also could have decided the result should have been Single.NaN (Not a Number), Single.MaxValue or even to throw an exception. But that's how it was implemented. The Single type (float in C#`) complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.

  • Related