Fixes classify function to detect subnormal floating points (#12836)

* Fix classify to test for subnormality.
* Minor fix.
* Modified to maintain existing API.
* Minor change.
* Removed 32-bit case since float is always 64-bit.
This commit is contained in:
KeepCoolWithCoolidge 2019-12-08 12:17:11 -07:00 • committed by Andreas Rumpf
commit ae7b53ec51

View file

@ -117,6 +117,8 @@ const
## meaningful digits ## meaningful digits
## after the decimal point ## after the decimal point
## for Nim's ``float`` type. ## for Nim's ``float`` type.
MinFloatNormal* = 2.225073858507201e-308 ## Smallest normal number for Nim's
## ``float`` type. (= 2^-1022).
RadPerDeg = PI / 180.0 ## Number of radians per degree RadPerDeg = PI / 180.0 ## Number of radians per degree
type type
@ -140,6 +142,7 @@ proc classify*(x: float): FloatClass =
doAssert classify(0.0) == fcZero doAssert classify(0.0) == fcZero
doAssert classify(0.3/0.0) == fcInf doAssert classify(0.3/0.0) == fcInf
doAssert classify(-0.3/0.0) == fcNegInf doAssert classify(-0.3/0.0) == fcNegInf
doAssert classify(5.0e-324) == fcSubnormal
# JavaScript and most C compilers have no classify: # JavaScript and most C compilers have no classify:
if x == 0.0: if x == 0.0:
@ -151,8 +154,9 @@ proc classify*(x: float): FloatClass =
if x > 0.0: return fcInf if x > 0.0: return fcInf
else: return fcNegInf else: return fcNegInf
if x != x: return fcNan if x != x: return fcNan
if abs(x) < MinFloatNormal:
return fcSubnormal
return fcNormal return fcNormal
# XXX: fcSubnormal is not detected!
proc isPowerOfTwo*(x: int): bool {.noSideEffect.} = proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
## Returns ``true``, if ``x`` is a power of two, ``false`` otherwise. ## Returns ``true``, if ``x`` is a power of two, ``false`` otherwise.