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