6 : shows hugeFloat ( '\n'
8 : shows tinyDouble ( '\n'
10 : shows hugeDouble ( '\n'
26 t_f = fromRationalX (toRational tinyFloat)
27 t_d = fromRationalX (toRational tinyDouble)
28 h_f = fromRationalX (toRational hugeFloat)
29 h_d = fromRationalX (toRational hugeDouble)
30 x_f = fromRationalX (1.82173691287639817263897126389712638972163e-300 :: Rational)
31 x_d = fromRationalX (1.82173691287639817263897126389712638972163e-300 :: Rational)
32 y_f = 1.82173691287639817263897126389712638972163e-300
33 y_d = 1.82173691287639817263897126389712638972163e-300
35 --!! fromRational woes
37 fromRationalX :: (RealFloat a) => Rational -> a
40 h = ceiling (huge `asTypeOf` x)
41 b = toInteger (floatRadix x)
44 let d = denominator r'
47 let e = integerLogBase b (d `div` h) + 1
48 in fromRat (e0-e) (n % (d `div` (b^e)))
49 else if abs n > h then
50 let e = integerLogBase b (abs n `div` h) + 1
51 in fromRat (e0+e) ((n `div` (b^e)) % d)
53 scaleFloat e0 (rationalToRealFloat {-fromRational-} r')
61 h = ceiling (huge `asTypeOf` x)
62 b = toInteger (floatRadix x)
66 {--} trace (shows e0 ('/' : shows r' ('/' : shows h "\n"))) (
67 let d = denominator r'
70 let e = integerLogBase b (d `div` h) + 1
71 in fromRat (e0-e) (n % (d `div` (b^e)))
72 else if abs n > h then
73 let e = integerLogBase b (abs n `div` h) + 1
74 in fromRat (e0+e) ((n `div` (b^e)) % d)
76 scaleFloat e0 (rationalToRealFloat r')
77 -- now that we know things are in-bounds,
78 -- we use the "old" Prelude code.
84 -- Compute the discrete log of i in base b.
85 -- Simplest way would be just divide i by b until it's smaller then b, but that would
86 -- be very slow! We are just slightly more clever.
87 integerLogBase :: Integer -> Integer -> Int
92 -- Try squaring the base first to cut down the number of divisions.
93 let l = 2 * integerLogBase (b*b) i
94 doDiv :: Integer -> Int -> Int
95 doDiv i l = if i < b then l else doDiv (i `div` b) (l+1)
96 in doDiv (i `div` (b^l)) l
101 -- Compute smallest and largest floating point values.
102 tiny :: (RealFloat a) => a
104 let (l, _) = floatRange x
105 x = encodeFloat 1 (l-1)
108 huge :: (RealFloat a) => a
110 let (_, u) = floatRange x
112 x = encodeFloat (floatRadix x ^ d - 1) (u - d)
115 tinyDouble = tiny :: Double
116 tinyFloat = tiny :: Float
117 hugeDouble = huge :: Double
118 hugeFloat = huge :: Float
121 [In response to a request by simonpj, Joe Fasel writes:]
123 A quite reasonable request! This code was added to the Prelude just
124 before the 1.2 release, when Lennart, working with an early version
125 of hbi, noticed that (read . show) was not the identity for
126 floating-point numbers. (There was a one-bit error about half the time.)
127 The original version of the conversion function was in fact simply
128 a floating-point divide, as you suggest above. The new version is,
129 I grant you, somewhat denser.
137 rationalToRealFloat :: (RealFloat a) => Rational -> a
139 rationalToRealFloat x = x'
142 -- If the exponent of the nearest floating-point number to x
143 -- is e, then the significand is the integer nearest xb^(-e),
144 -- where b is the floating-point radix. We start with a good
145 -- guess for e, and if it is correct, the exponent of the
146 -- floating-point number we construct will again be e. If
147 -- not, one more iteration is needed.
149 f e = if e' == e then y else f e'
150 where y = encodeFloat (round (x * (1%b)^^e)) e
151 (_,e') = decodeFloat y
154 -- We obtain a trial exponent by doing a floating-point
155 -- division of x's numerator by its denominator. The
156 -- result of this division may not itself be the ultimate
157 -- result, because of an accumulation of three rounding
160 (s,e) = decodeFloat (fromInteger (numerator x) `asTypeOf` x'
161 / fromInteger (denominator x))