[clean-list] Python's "fix" function in Clean
Siegfried Gonzi
siegfried.gonzi@stud.uni-graz.at
Tue, 06 May 2003 11:23:03 +0200
>
>
>
I once complaint about Clean's scarce libraries for handling formatted
output. The following is a first step:
Maybe you are already familar with Python's fix function:
==
from fpformat import*
fix(2.23231312123123312312,2)
==
fix convertes a number to a specific precision and if needed fills up
traling zeros and delivers a string for formatted output, e.g:
fix(2.3,3) -> 2.300
I wrote a similar function for Clean (you can literally translate it to
Haskell), with the caveat that it only works the same as Python's fix
for floating point values with single precision. The crux actually is
that Clean's native "toString" function "fails" when converting a huge
integer number. I think Python uses some bit representation, because
this works under Python: fix(32231231123123124433422352545.3545544545,123)
My Clean version works right with the small "drawback" that if a number
is greater than 10^9 it is given back as toString(x) and if the
precision is specified greater than 9 it will be set back to 9, e.g.
(fix 2.3 120) would result in 2.300000000 and not in 2.300000000000.....
as it would happen under Python's fix. But who wants to store a number
with 120 "pseudo" precision digits?
You can convert Clean's fix function for formatted output:
==
module fix9
import StdEnv
fix:: Real Int -> String
fix val n
# n = (if (n>9) 9 n)
| abs(val)>=10.0^9.0 = toString(val)
| n<0 = "0"
| n==0 = toString(toInt(round val))
# exp_n = 10.0^toReal(n)
# f = (round (val*exp_n))/exp_n
# f = abs val
# t = toInt(truncate f)
# s = toString(toInt(round (exp_n*(f-toReal(t)))))
# nzeros = length [x\\x<-:s]
= (whatSign val)+++(toStringt)
+++"."+++{'0'\\x<-[1..(n-nzeros)]}+++s
where
round:: Real -> Real
round x = toReal(toInt(x))
//
truncate:: Real -> Real
truncate x
| x<0.0 = toReal(toInt(x+0.5))
= toReal(toInt(x-0.5))
//
whatSign::Real -> String
whatSign x
| x<0.0 = "-"
= ""
//Start = fix (-0.000011) 2
//Start = fix 2.333333 1
//Start = fix 0.01 3
//Start = fix 0.01 0
//Start = fix -2322332231312312123312123.33 12
Start = fix 1234.34 5
==
fix 0.03 0 --> "0"
fix -2.334444 1 --> "-2.3"
fix 2.3454 5 --> "2.34540"
fix 2.89 1 --> "2.9"
fix (10.0^12.0) 123 --> "1e12" (Clean's native toString and Python would
put out a very long string; but as I said my function would also work
right if toString were not limited to 32bit, I think)
Regards,
S. Gonzi