diff options
author | KeepCoolWithCoolidge <37387200+KeepCoolWithCoolidge@users.noreply.github.com> | 2019-12-08 12:17:11 -0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-12-08 20:17:11 +0100 |
commit | ae7b53ec51c474b8da4fbfc2778352b07ddb7b53 (patch) | |
tree | ae5339b0ced19d172134e6f574479547dff7f740 | |
parent | 5da27a891c99de462fd8d5019662c47b311c8ff9 (diff) | |
download | Nim-ae7b53ec51c474b8da4fbfc2778352b07ddb7b53.tar.gz |
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.
-rw-r--r-- | lib/pure/math.nim | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 27e3e507d..362472584 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -103,21 +103,23 @@ when defined(Posix) and not defined(genode): {.passl: "-lm".} const - PI* = 3.1415926535897932384626433 ## The circle constant PI (Ludolph's number) - TAU* = 2.0 * PI ## The circle constant TAU (= 2 * PI) - E* = 2.71828182845904523536028747 ## Euler's number - - MaxFloat64Precision* = 16 ## Maximum number of meaningful digits - ## after the decimal point for Nim's - ## ``float64`` type. - MaxFloat32Precision* = 8 ## Maximum number of meaningful digits - ## after the decimal point for Nim's - ## ``float32`` type. - MaxFloatPrecision* = MaxFloat64Precision ## Maximum number of - ## meaningful digits - ## after the decimal point - ## for Nim's ``float`` type. - RadPerDeg = PI / 180.0 ## Number of radians per degree + PI* = 3.1415926535897932384626433 ## The circle constant PI (Ludolph's number) + TAU* = 2.0 * PI ## The circle constant TAU (= 2 * PI) + E* = 2.71828182845904523536028747 ## Euler's number + + MaxFloat64Precision* = 16 ## Maximum number of meaningful digits + ## after the decimal point for Nim's + ## ``float64`` type. + MaxFloat32Precision* = 8 ## Maximum number of meaningful digits + ## after the decimal point for Nim's + ## ``float32`` type. + MaxFloatPrecision* = MaxFloat64Precision ## Maximum number of + ## meaningful digits + ## after the decimal point + ## 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 type FloatClass* = enum ## Describes the class a floating point value belongs to. @@ -140,6 +142,7 @@ proc classify*(x: float): FloatClass = doAssert classify(0.0) == fcZero doAssert classify(0.3/0.0) == fcInf doAssert classify(-0.3/0.0) == fcNegInf + doAssert classify(5.0e-324) == fcSubnormal # JavaScript and most C compilers have no classify: if x == 0.0: @@ -151,8 +154,9 @@ proc classify*(x: float): FloatClass = if x > 0.0: return fcInf else: return fcNegInf if x != x: return fcNan + if abs(x) < MinFloatNormal: + return fcSubnormal return fcNormal - # XXX: fcSubnormal is not detected! proc isPowerOfTwo*(x: int): bool {.noSideEffect.} = ## Returns ``true``, if ``x`` is a power of two, ``false`` otherwise. |