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
, andDecimal
, etc.? - Why does
(float.MaxValue / float.Epsilon)
evaluate to Infinity? Should it not evaluate to a number very close to, but less thanfloat.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 ofInt64
.BigInteger
could also be used to represent the range offloat
anddouble
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 thanfloat.MaxValue
in afloat
, Microsoft decided to assign itSingle.PositiveInfinity
instead. They also could have decided the result should have beenSingle.NaN
(Not a Number),Single.MaxValue
or even to throw an exception. But that's how it was implemented. TheSingle
type (float
in C#`) complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.