Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
GHC
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Gesh
GHC
Commits
613558d8
Commit
613558d8
authored
27 years ago
by
Simon Marlow
Browse files
Options
Downloads
Patches
Plain Diff
[project @ 1997-09-26 13:38:58 by simonm]
this file got lost somehow
parent
7908b385
Loading
Loading
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ghc/tests/codeGen/should_run/cg034.hs
+162
-0
162 additions, 0 deletions
ghc/tests/codeGen/should_run/cg034.hs
with
162 additions
and
0 deletions
ghc/tests/codeGen/should_run/cg034.hs
0 → 100644
+
162
−
0
View file @
613558d8
import
Ratio
-- 1.3
main
=
putStr
(
shows
tinyFloat
(
'
\n
'
:
shows
t_f
(
'
\n
'
:
shows
hugeFloat
(
'
\n
'
:
shows
h_f
(
'
\n
'
:
shows
tinyDouble
(
'
\n
'
:
shows
t_d
(
'
\n
'
:
shows
hugeDouble
(
'
\n
'
:
shows
h_d
(
'
\n
'
:
shows
x_f
(
'
\n
'
:
shows
x_d
(
'
\n
'
:
shows
y_f
(
'
\n
'
:
shows
y_d
(
"
\n
"
)))))))))))))
where
t_f
::
Float
t_d
::
Double
h_f
::
Float
h_d
::
Double
x_f
::
Float
x_d
::
Double
y_f
::
Float
y_d
::
Double
t_f
=
fromRationalX
(
toRational
tinyFloat
)
t_d
=
fromRationalX
(
toRational
tinyDouble
)
h_f
=
fromRationalX
(
toRational
hugeFloat
)
h_d
=
fromRationalX
(
toRational
hugeDouble
)
x_f
=
fromRationalX
(
1.82173691287639817263897126389712638972163e-300
::
Rational
)
x_d
=
fromRationalX
(
1.82173691287639817263897126389712638972163e-300
::
Rational
)
y_f
=
1.82173691287639817263897126389712638972163e-300
y_d
=
1.82173691287639817263897126389712638972163e-300
--!!
fromRational
woes
fromRationalX
::
(
RealFloat
a
)
=>
Rational
->
a
fromRationalX
r
=
let
h
=
ceiling
(
huge
`
asTypeOf
`
x
)
b
=
toInteger
(
floatRadix
x
)
x
=
fromRat
0
r
fromRat
e0
r'
=
let
d
=
denominator
r'
n
=
numerator
r'
in
if
d
>
h
then
let
e
=
integerLogBase
b
(
d
`
div
`
h
)
+
1
in
fromRat
(
e0
-
e
)
(
n
%
(
d
`
div
`
(
b
^
e
)))
else
if
abs
n
>
h
then
let
e
=
integerLogBase
b
(
abs
n
`
div
`
h
)
+
1
in
fromRat
(
e0
+
e
)
((
n
`
div
`
(
b
^
e
))
%
d
)
else
scaleFloat
e0
(
rationalToRealFloat
{-fromRational-}
r'
)
in
x
{-
fromRationalX r =
rationalToRealFloat r
{- Hmmm...
let
h = ceiling (huge `asTypeOf` x)
b = toInteger (floatRadix x)
x = fromRat 0 r
fromRat e0 r' =
{--} trace (shows e0 ('/' : shows r' ('/' : shows h "\n"))) (
let d = denominator r'
n = numerator r'
in if d > h then
let e = integerLogBase b (d `div` h) + 1
in fromRat (e0-e) (n % (d `div` (b^e)))
else if abs n > h then
let e = integerLogBase b (abs n `div` h) + 1
in fromRat (e0+e) ((n `div` (b^e)) % d)
else
scaleFloat e0 (rationalToRealFloat r')
-- now that we know things are in-bounds,
-- we use the "old" Prelude code.
{--} )
in x
-}
-}
-- Compute the discrete log of i in base b.
-- Simplest way would be just divide i by b until it's smaller then b, but that would
-- be very slow! We are just slightly more clever.
integerLogBase
::
Integer
->
Integer
->
Int
integerLogBase
b
i
=
if
i
<
b
then
0
else
-- Try squaring the base first to cut down the number of divisions.
let
l
=
2
*
integerLogBase
(
b
*
b
)
i
doDiv
::
Integer
->
Int
->
Int
doDiv
i
l
=
if
i
<
b
then
l
else
doDiv
(
i
`
div
`
b
)
(
l
+
1
)
in
doDiv
(
i
`
div
`
(
b
^
l
))
l
------------
-- Compute smallest and largest floating point values.
tiny
::
(
RealFloat
a
)
=>
a
tiny
=
let
(
l
,
_
)
=
floatRange
x
x
=
encodeFloat
1
(
l
-
1
)
in
x
huge
::
(
RealFloat
a
)
=>
a
huge
=
let
(
_
,
u
)
=
floatRange
x
d
=
floatDigits
x
x
=
encodeFloat
(
floatRadix
x
^
d
-
1
)
(
u
-
d
)
in
x
tinyDouble
=
tiny
::
Double
tinyFloat
=
tiny
::
Float
hugeDouble
=
huge
::
Double
hugeFloat
=
huge
::
Float
{-
[In response to a request by simonpj, Joe Fasel writes:]
A quite reasonable request! This code was added to the Prelude just
before the 1.2 release, when Lennart, working with an early version
of hbi, noticed that (read . show) was not the identity for
floating-point numbers. (There was a one-bit error about half the time.)
The original version of the conversion function was in fact simply
a floating-point divide, as you suggest above. The new version is,
I grant you, somewhat denser.
How's this?
--Joe
-}
rationalToRealFloat
::
(
RealFloat
a
)
=>
Rational
->
a
rationalToRealFloat
x
=
x'
where
x'
=
f
e
-- If the exponent of the nearest floating-point number to x
-- is e, then the significand is the integer nearest xb^(-e),
-- where b is the floating-point radix. We start with a good
-- guess for e, and if it is correct, the exponent of the
-- floating-point number we construct will again be e. If
-- not, one more iteration is needed.
f
e
=
if
e'
==
e
then
y
else
f
e'
where
y
=
encodeFloat
(
round
(
x
*
(
1
%
b
)
^^
e
))
e
(
_
,
e'
)
=
decodeFloat
y
b
=
floatRadix
x'
-- We obtain a trial exponent by doing a floating-point
-- division of x's numerator by its denominator. The
-- result of this division may not itself be the ultimate
-- result, because of an accumulation of three rounding
-- errors.
(
s
,
e
)
=
decodeFloat
(
fromInteger
(
numerator
x
)
`
asTypeOf
`
x'
/
fromInteger
(
denominator
x
))
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment