1 -- !!! Testing IEEE Float and Double extremity predicates.
2 module Main(main) where
10 sequence_ (map putStrLn double_tests)
11 sequence_ (map putStrLn float_tests)
13 double_tests = run_tests double_numbers
14 float_tests = run_tests float_numbers
27 double_numbers :: [Double]
30 , encodeFloat 0 0 -- 0 using encodeFloat method
31 , mkDouble (map chr [0,0,0,0,0,0, 0xf0, 0x7f]) -- +inf
32 , encodeFloat 1 2047 -- +Inf
34 , encodeFloat 1 2047 -- signalling NaN
35 , encodeFloat 0xf000000000000 2047 -- quiet NaN
38 , 1.82173691287639817263897126389712638972163e-300
39 , 1.82173691287639817263897126389712638972163e+300
40 , 4.9406564558412465e-324 -- smallest possible denorm number
41 -- (as reported by enquire running
42 -- on a i686-pc-linux.)
43 , 2.2250738585072014e-308
48 , let (l, _) = floatRange x
49 x = encodeFloat 1 (l-1)
52 , let (_, u) = floatRange x
54 x = encodeFloat (floatRadix x ^ d - 1) (u - d)
58 float_numbers :: [Float]
61 , encodeFloat 0 0 -- 0 using encodeFloat method
62 , encodeFloat 1 255 -- +Inf
64 , encodeFloat 11 255 -- signalling NaN
65 , encodeFloat 0xf00000 255 -- quiet NaN
68 , 1.82173691287639817263897126389712638972163e-300
69 , 1.82173691287639817263897126389712638972163e+300
77 , let (l, _) = floatRange x
78 x = encodeFloat 1 (l-1)
81 , let (_, u) = floatRange x
83 x = encodeFloat (floatRadix x ^ d - 1) (u - d)
89 denorm :: RealFloat a => [a] -> String
93 : "*********************************"
94 : ("Denormalised numbers: " ++ doubleOrFloat numbers)
96 : map showPerform numbers)
98 showPerform = showAndPerform (isDenormalized) "isDenormalised"
100 pos_inf :: RealFloat a => [a] -> String
104 : "*********************************"
105 : ("Positive Infinity: " ++ doubleOrFloat numbers)
107 : map showPerform numbers)
109 showPerform = showAndPerform (isInfinite) "isInfinite"
111 neg_inf :: RealFloat a => [a] -> String
115 : "*********************************"
116 : ("Negative Infinity: " ++ doubleOrFloat numbers)
118 : map showPerform numbers)
120 showPerform = showAndPerform (\ x -> isInfinite x && x < 0) "isNegInfinite"
122 nan :: RealFloat a => [a] -> String
126 : "*********************************"
127 : ("NaN: " ++ doubleOrFloat numbers)
129 : map showPerform numbers)
131 showPerform = showAndPerform (isNaN) "isNaN"
133 pos_zero :: RealFloat a => [a] -> String
137 : "*********************************"
138 : ("Positive zero: " ++ doubleOrFloat numbers)
140 : map showPerform numbers)
142 showPerform = showAndPerform (==0) "isPosZero"
144 neg_zero :: RealFloat a => [a] -> String
148 : "*********************************"
149 : ("Negative zero: " ++ doubleOrFloat numbers)
151 : map showPerform numbers)
153 showPerform = showAndPerform (isNegativeZero) "isNegativeZero"
156 doubleOrFloat :: RealFloat a => [a] -> String
158 | (floatDigits atType) == (floatDigits (0::Double)) = "Double"
159 | (floatDigits atType) == (floatDigits (0::Float)) = "Float"
160 | otherwise = "unknown RealFloat type"
162 atType = undefined `asTypeOf` (head ls)
164 -- make a double from a list of 8 bytes
165 -- (caller deals with byte ordering.)
166 mkDouble :: [Char] -> Double
169 arr <- newCharArray (0,7)
170 sequence (zipWith (writeCharArray arr) [(0::Int)..] (take 8 ls))
171 readDoubleArray arr 0
174 showAndPerform :: (Show a, Show b)
179 showAndPerform fun name_fun val =
180 name_fun ++ ' ':show val ++ " = " ++ show (fun val)