Skip to content

Commit ae7b53e

Browse files
KeepCoolWithCoolidgeAraq
authored andcommitted
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.
1 parent 5da27a8 commit ae7b53e

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

lib/pure/math.nim

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,23 @@ when defined(Posix) and not defined(genode):
103103
{.passl: "-lm".}
104104

105105
const
106-
PI* = 3.1415926535897932384626433 ## The circle constant PI (Ludolph's number)
107-
TAU* = 2.0 * PI ## The circle constant TAU (= 2 * PI)
108-
E* = 2.71828182845904523536028747 ## Euler's number
109-
110-
MaxFloat64Precision* = 16 ## Maximum number of meaningful digits
111-
## after the decimal point for Nim's
112-
## ``float64`` type.
113-
MaxFloat32Precision* = 8 ## Maximum number of meaningful digits
114-
## after the decimal point for Nim's
115-
## ``float32`` type.
116-
MaxFloatPrecision* = MaxFloat64Precision ## Maximum number of
117-
## meaningful digits
118-
## after the decimal point
119-
## for Nim's ``float`` type.
120-
RadPerDeg = PI / 180.0 ## Number of radians per degree
106+
PI* = 3.1415926535897932384626433 ## The circle constant PI (Ludolph's number)
107+
TAU* = 2.0 * PI ## The circle constant TAU (= 2 * PI)
108+
E* = 2.71828182845904523536028747 ## Euler's number
109+
110+
MaxFloat64Precision* = 16 ## Maximum number of meaningful digits
111+
## after the decimal point for Nim's
112+
## ``float64`` type.
113+
MaxFloat32Precision* = 8 ## Maximum number of meaningful digits
114+
## after the decimal point for Nim's
115+
## ``float32`` type.
116+
MaxFloatPrecision* = MaxFloat64Precision ## Maximum number of
117+
## meaningful digits
118+
## after the decimal point
119+
## for Nim's ``float`` type.
120+
MinFloatNormal* = 2.225073858507201e-308 ## Smallest normal number for Nim's
121+
## ``float`` type. (= 2^-1022).
122+
RadPerDeg = PI / 180.0 ## Number of radians per degree
121123

122124
type
123125
FloatClass* = enum ## Describes the class a floating point value belongs to.
@@ -140,6 +142,7 @@ proc classify*(x: float): FloatClass =
140142
doAssert classify(0.0) == fcZero
141143
doAssert classify(0.3/0.0) == fcInf
142144
doAssert classify(-0.3/0.0) == fcNegInf
145+
doAssert classify(5.0e-324) == fcSubnormal
143146

144147
# JavaScript and most C compilers have no classify:
145148
if x == 0.0:
@@ -151,8 +154,9 @@ proc classify*(x: float): FloatClass =
151154
if x > 0.0: return fcInf
152155
else: return fcNegInf
153156
if x != x: return fcNan
157+
if abs(x) < MinFloatNormal:
158+
return fcSubnormal
154159
return fcNormal
155-
# XXX: fcSubnormal is not detected!
156160

157161
proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
158162
## Returns ``true``, if ``x`` is a power of two, ``false`` otherwise.

0 commit comments

Comments
 (0)