C# has three mathematical constants that look like constants in the C header file float.h
. Two of these are not what you might expect.
The constant double.MaxValue
in C# looks like the constant DBL_MAX
in C, and indeed it is. Both give the maximum finite value of a double
, which is on the order of 10^308. This might lead you to believe that double.MinValue
in C# is the same as DBL_MIN
in C or that double.Epsilon
in C# is the same as DBL_EPSILON
. If so, you’re in for a surprise.
The constants DBL_MAX
and double.MaxValue
are the same because there is no ambiguity over what “max” means: the largest finite value of a double
. But DBL_MIN
and double.MinValue
are different because they minimize over different ranges. The constant DBL_MIN
is the smallest positive value of a normalized double
. The constant double.MinValue
in C# is the smallest (i.e. most negative) value of a double
and is the negative of double.MaxValue
. The difference between DBL_MIN
and double.MinValue
is approximately the difference between 10^-308 and -10^308, between a very small positive number and a very large negative number.
C has a constant DBL_EPSILON
for the smallest positive double precision number x
such that 1 + x
does not equal 1 in machine precision. Typically a double
has about 15 figures of precision, and so DBL_EPSILON
is on the order of 10^−16. (For a more precise description, see Anatomy of a floating point number.)
You might expect double.Epsilon
in C# corresponds to DBL_EPSILON
in C. I did, until a unit test failed on some numerical code I was porting from C++ to C#. But in C# double.Epsilon
is the smallest positive value a (denormalized) double
can take. It is similar to DBL_MIN
, except that double.Epsilon
is the possible smallest value of a double
, not requiring normalization. The constant DBL_MIN
is on the order of 10^−308 while double.Epsilon
is on the order of 10^−324 because it allows denormalized values. (See Anatomy of a floating point number for details of denormalized numbers.)
Incidentally, the C constants DBL_MAX
, DBL_MIN
, and DBL_EPSILON
equal the return values of max
, min
, and epsilon
for the C++ class numeric_limits<double>
.
To summarize,
double.MaxValue
in C# equals DBL_MAX
in C.
double.MinValue
in C# equals -DBL_MAX
in C.
double.Epsilon
is similar to DBL_MIN
in C, but orders of magnitude smaller.
- C# has no analog of
DBL_EPSILON
from C.
One could argue that the C# names are better than the C names. It makes sense for double.MinValue
to be the negative of double.MaxValue
. But the use of Epsilon
was a mistake. The term “epsilon” in numeric computing has long been established and is not limited to C. It would have been better if Microsoft had used the name MinPositiveValue
to be more explicit and not conflict with established terminology.
Related posts