RE: fraclib.e

new topic     » goto parent     » topic index » view thread      » older message » newer message

Have you tried the free ABC programming language from the Netherlands? They
do this kind of thing apparently with infinite precision. I don't know how
they do that. Maybe you could contact them to learn the basis of their
algorithm.
Regards.
----- Original Message -----
From: <jbrown1050 at hotpop.com>
Subject: fraclib.e


>
> I'm wrote this very simple lib, which gives infinite precision for
rational
> numbers by storing numbers as fractions, i.e. "1/3 * 3" (actually,
> "f_mul({1,3}, {3,1})" using my lib) returns 1, rather than 0.9999999999
>
> It stores fractions as a 2 element biginteger sequence. (A biginteger
> is currently an atom thats restricted to whole numbers, I eventually plan
> to add a bignum library to it, so you are not limited by the +/-1e300
> size of an atom.)
>
> If you try out this line, "? atom_to_f(f_to_atom({1,3}))", via my lib,
> you'll find it takes a VERY long time to compute. This is because my
> reduce() function is not very optimized. Any one have any ideas on how it
> could be made faster?
>
> TIA,
> jbrown
>
> My lib is pasted into my signature space at the bottom of this email.
>
> --
> include get.e
> include misc.e
>
> global type biginteger(object a)
> if not atom(a) then
> return 0
> end if
> if floor(a) != a then
> return 0
> end if
> return 1
> end type
>
> global type fraction(object s)
> if not sequence(s) then
> return 0
> end if
> if length(s) != 2 then
> return 0
> end if
> if not(biginteger(s[1]) and biginteger(s[2])) then
> return 0
> end if
> return 1
> end type
>
> function gcd(biginteger num1, biginteger num2)
> biginteger gcd_val
> if num1 > num2 then
> gcd_val = num1
> else
> gcd_val = num2
> end if
> while remainder(num1, gcd_val) != 0
> or remainder(num2, gcd_val) != 0 do
> gcd_val -= 1
> end while
> return gcd_val
> end function
> function reduce(fraction f)
> if f[2] = 0 then
> f[2] /= 0 --trigger an error here.
> end if
> return f / gcd(f[1], f[2])
> end function
>
> global function f_mul(fraction f1, fraction f2)
> return reduce({f1[1]*f2[1], f1[2]*f2[2]})
> end function
>
> global function f_div(fraction f1, fraction f2)
> return f_mul(f1, {f2[2], f2[1]})
> end function
>
> global function f_add(fraction f1, fraction f2)
> biginteger f1_dem, f2_dem
> f1_dem = f1[2]
> f2_dem = f2[2]
> f1 *= f2_dem
> f2 *= f1_dem
> return reduce({f1[1]+f2[1], f1[2]})
> end function
>
> global function f_sub(fraction f1, fraction f2)
> biginteger f1_dem, f2_dem
> f1_dem = f1[2]
> f2_dem = f2[2]
> f1 *= f2_dem
> f2 *= f1_dem
> return reduce({f1[1]-f2[1], f1[2]})
> end function
>
> global function f_to_atom(fraction f)
> return f[1]/f[2]
> end function
>
> global function f_to_string(fraction f)
> return sprintf("%d/%d", f)
> end function
>
> global function string_to_f(sequence s)
<snip>

>
>

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu