Infinity, NaN and negative zero
A float64 can hold more than numbers: positive and negative infinity, NaN
("not a number", the result of an operation with no answer), and a zero with a
sign. Floating point does not wrap on overflow; it goes to infinity.
#import "std/numeric"
'' Infinity and NaN are made by functions, not constants.
var inf = numeric.Infinity( )
var nan_ = numeric.NaN( )
'' Overflow in floating point gives infinity, not a wrapped value.
dim as float64 big = 1e308
print "1e308 * 10 is infinite: "; numeric.IsInfinite( big * 10 )
print "inf > 1e308: "; cbool( inf > big )
print "inf - inf is NaN: "; numeric.IsNaN( inf - inf )
'' A NaN equals nothing, not even itself: ask with IsNaN.
print "nan = nan: "; cbool( nan_ = nan_ )
print "IsNaN( nan ): "; numeric.IsNaN( nan_ )
'' Classify names the kind of value.
print "Classify( 0.0 ) is FP_ZERO: "; _
cbool( numeric.Classify( 0.0 ) = numeric.FP_ZERO )
print "Classify( 1.0 ) is FP_NORMAL: "; _
cbool( numeric.Classify( 1.0 ) = numeric.FP_NORMAL )
'' Two zeros: equal as numbers, different in the sign bit.
dim as float64 negZero = -0.0
print "-0 = 0: "; cbool( negZero = 0.0 ); _
", IsNegative( -0 ): "; numeric.IsNegative( negZero )
print "1 / -0 is negative infinity: "; _
cbool( 1 / negZero = numeric.NegInfinity( ) )
'' The library passes a NaN on rather than dropping it.
print "Max( nan, 1 ) is NaN: "; numeric.IsNaN( numeric.Max( nan_, 1.0 ) )
Output
1e308 * 10 is infinite: true
inf > 1e308: true
inf - inf is NaN: true
nan = nan: false
IsNaN( nan ): true
Classify( 0.0 ) is FP_ZERO: true
Classify( 1.0 ) is FP_NORMAL: true
-0 = 0: true, IsNegative( -0 ): true
1 / -0 is negative infinity: true
Max( nan, 1 ) is NaN: true
numeric.Infinity( ), NegInfinity( ) and NaN( ) make the special values.
They are functions because a constant cannot be initialised by dividing by zero.
A NaN is not equal to anything, itself included, so x = x is false for a
NaN. Ask IsNaN( x ). IsInfinite, IsFinite, IsNormal and IsSubnormal
complete the questions, and Classify( x ) names the kind: FP_NAN,
FP_INFINITE, FP_ZERO, FP_SUBNORMAL or FP_NORMAL.
-0.0 and 0.0 are equal as numbers and differ in the sign bit, which
IsNegative reads. The sign shows when you divide by it: one over negative
zero is negative infinity.
The library passes a NaN on rather than dropping it: Max( NaN, 1 ) is NaN.
Losing the NaN there would turn an error you could find into a wrong answer you
could not.
The example prints tests of the values rather than the values. How print
shows an infinity or a NaN is the runtime's choice; a test means the same on
every platform.
Activities
- Print
IsNaN( sqr( -1 ) ). - Find the smallest power of ten that is infinite in a
float64with a loop andIsInfinite.