Continued fraction/Arithmetic/Construct from rational number: Difference between revisions
Content deleted Content added
Line 381: | Line 381: | ||
Note that [3; 6, 1] is equal to [3; 7]. |
Note that [3; 6, 1] is equal to [3; 7]. |
||
</pre> |
|||
=== Using multiple precision numbers === |
|||
For this you need the [https://sourceforge.net/p/chemoelectric/ats2-xprelude '''ats2-xprelude'''] package. I start with octuple precision (IEEE binary256) approximations to the square root of 2 and 22/7. |
|||
<syntaxhighlight lang="ats"> |
|||
(*------------------------------------------------------------------*) |
|||
(* A version that uses the ats2-xprelude package |
|||
https://sourceforge.net/p/chemoelectric/ats2-xprelude |
|||
With ats2-xprelude installed, you can run the program with |
|||
something like: |
|||
patscc -DATS_MEMALLOC_GCBDW `pkg-config --variable=PATSCCFLAGS ats2-xprelude` \ |
|||
`pkg-config --cflags ats2-xprelude` -O2 -std=gnu2x \ |
|||
continued-fraction-from-rational-2.dats \ |
|||
`pkg-config --libs ats2-xprelude` -lgc && ./a.out |
|||
*) |
|||
#include "share/atspre_staload.hats" |
|||
#include "xprelude/HATS/xprelude.hats" |
|||
staload "xprelude/SATS/exrat.sats" |
|||
staload _ = "xprelude/DATS/exrat.dats" |
|||
staload "xprelude/SATS/mpfr.sats" |
|||
staload _ = "xprelude/DATS/mpfr.dats" |
|||
(*------------------------------------------------------------------*) |
|||
fn |
|||
step (ratnum : ref exrat, |
|||
done : ref bool) |
|||
: exrat = |
|||
let |
|||
(* Effectively we are doing the same thing as if we used integer |
|||
floor division and the denominator were kept positive. *) |
|||
val q = floor !ratnum |
|||
val diff = !ratnum - q |
|||
in |
|||
if iseqz diff then |
|||
begin |
|||
!done := true; |
|||
q |
|||
end |
|||
else |
|||
begin |
|||
!ratnum := reciprocal diff; |
|||
q |
|||
end |
|||
end |
|||
fn |
|||
r2cf (ratnum : exrat) |
|||
: () -<cloref1> Option exrat = |
|||
let |
|||
val ratnum = ref<exrat> ratnum |
|||
and done = ref<bool> false |
|||
in |
|||
lam () => |
|||
if !done then |
|||
None () |
|||
else |
|||
Some (step (ratnum, done)) |
|||
end |
|||
(*------------------------------------------------------------------*) |
|||
fn |
|||
print_digits (f : () -<cloref1> Option exrat) |
|||
: void = |
|||
let |
|||
fun |
|||
loop (sep : string) |
|||
: void = |
|||
case+ f () of |
|||
| None () => println! ("]") |
|||
| Some d => |
|||
begin |
|||
print! (sep, d); |
|||
if sep = "[" then |
|||
loop "; " |
|||
else |
|||
loop ", " |
|||
end |
|||
in |
|||
loop "[" |
|||
end |
|||
fn {tk : tkind} |
|||
print_continued_fraction |
|||
(ratnum : exrat) |
|||
: void = |
|||
begin |
|||
print! (ratnum, " => "); |
|||
print_digits (r2cf ratnum) |
|||
end |
|||
(*------------------------------------------------------------------*) |
|||
(* The number of bits in the significand of an IEEE binary256 |
|||
floating point number. *) |
|||
#define OCTUPLE_PREC 237 |
|||
implement |
|||
main0 () = |
|||
begin |
|||
print_continued_fraction (exrat_make (1, 2)); |
|||
print_continued_fraction (exrat_make (3, 1)); |
|||
print_continued_fraction (exrat_make (23, 8)); |
|||
print_continued_fraction (exrat_make (13, 11)); |
|||
print_continued_fraction (exrat_make (22, 7)); |
|||
print_continued_fraction (exrat_make (~151, 77)); |
|||
let |
|||
val sqrt2 : mpfr = mpfr_SQRT2 OCTUPLE_PREC |
|||
val sqrt2 : exrat = g0f2f sqrt2 |
|||
in |
|||
println! ("Octuple precision sqrt2:"); |
|||
print_continued_fraction sqrt2 |
|||
end; |
|||
let |
|||
val val_22_7 : mpfr = |
|||
mpfr_make ("22", OCTUPLE_PREC) / mpfr_make ("7", OCTUPLE_PREC) |
|||
val val_22_7 : exrat = g0f2f val_22_7 |
|||
in |
|||
println! ("Octuple precision 22/7:"); |
|||
print_continued_fraction val_22_7 |
|||
end; |
|||
end |
|||
(*------------------------------------------------------------------*) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> $ patscc -DATS_MEMALLOC_GCBDW `pkg-config --variable=PATSCCFLAGS ats2-xprelude` `pkg-config --cflags ats2-xprelude` -O2 -std=gnu2x continued-fraction-from-rational-2.dats `pkg-config --libs ats2-xprelude` -lgc -lm && ./a.out |
|||
1/2 => [0; 2] |
|||
3 => [3] |
|||
23/8 => [2; 1, 7] |
|||
13/11 => [1; 5, 2] |
|||
22/7 => [3; 7] |
|||
-151/77 => [-2; 25, 1, 2] |
|||
Octuple precision sqrt2: |
|||
78084346301521422975112153571109417254931862326853978216001371002918963/55213970774324510299478046898216203619608871777363092441300193790394368 => [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 6, 1, 38, 2, 1, 9, 3, 16, 2, 1, 10, 2, 2, 1, 1, 18, 1, 2, 1, 3, 4, 1, 1, 2, 6, 6, 4, 3, 2, 1, 2, 4, 2, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 2, 4, 1, 7, 10, 2, 1, 4, 3, 40, 1, 1, 5, 1, 2, 2, 1, 1, 7, 7, 6, 7, 1, 1, 2, 2] |
|||
Octuple precision 22/7: |
|||
86764811216795659042036930840054034259385369935856288122043161670619721/27606985387162255149739023449108101809804435888681546220650096895197184 => [3; 7, 3943855055308893592819860492729728829972062269811649460092870985028169] |
|||
</pre> |
</pre> |
||