Continued fraction/Arithmetic/Construct from rational number: Difference between revisions

Line 2,564:
{1, 2, 2, 2, 2, 2, 2, 2, 3, 6, 1, 2, 1, 12}
{1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 1, 2, 4, 1, 1, 2}</pre>
 
=={{header|Mercury}}==
{{works with|Mercury|22.01.1}}
<syntaxhighlight lang="mercury">%%%-------------------------------------------------------------------
 
:- module continued_fraction_from_rational.
 
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module int.
:- import_module list.
:- import_module string.
 
%%%-------------------------------------------------------------------
%%%
%%% ‘r2cf’ is a predicate, not a function. If it succeeds, it
%%% calculates not only the next digit, but the next starting
%%% fraction. If it fails, we are done.
%%%
 
:- pred r2cf(int::in, int::out, int::in, int::out, int::out)
is semidet.
r2cf(!N1, !N2, Digit) :-
(Dividend = !.N1),
(Divisor = !.N2),
(Divisor \= 0), % Fail is we have reached the end.
(!:N1 = Divisor), % The next Dividend.
(!:N2 = Dividend mod Divisor), % Floor division. The next divisor.
(Digit = Dividend div Divisor). % Floor division. The next digit.
 
%%%-------------------------------------------------------------------
%%%
%%% ‘r2cf_digits’ takes numerator and denominator of a rational
%%% number, and returns a list of continued fraction digits.
%%%
 
:- func r2cf_digits(int, int) = list(int).
:- pred r2cf_digits_loop(int::in, int::in,
list(int)::in, list(int)::out) is det.
r2cf_digits(N1, N2) = Digit_list :-
r2cf_digits_loop(N1, N2, [], Digit_list).
r2cf_digits_loop(N1, N2, !Digit_list) :-
(if r2cf(N1, N1_next, N2, N2_next, Digit)
then r2cf_digits_loop(N1_next, N2_next,
[Digit | !.Digit_list],
!:Digit_list)
else (!:Digit_list = reverse(!.Digit_list))).
 
%%%-------------------------------------------------------------------
%%%
%%% ‘print_cf’ prints a continued fraction nicely.
%%%
 
:- pred print_cf(list(int)::in, io::di, io::uo) is det.
:- pred print_cf_loop(list(int)::in, string::in, io::di, io::uo)
is det.
print_cf(Digit_list, !IO) :-
print_cf_loop(Digit_list, "[", !IO).
print_cf_loop(Digit_list, Sep, !IO) :-
(if (Digit_list = [Digit | More_digits])
then (print(Sep, !IO),
print(Digit, !IO),
(if (Sep = "[")
then print_cf_loop(More_digits, "; ", !IO)
else print_cf_loop(More_digits, ", ", !IO)))
else print("]", !IO)).
 
%%%-------------------------------------------------------------------
%%%
%%% ‘example’ takes numerator and denominator of a rational number,
%%% and prints a line of output.
%%%
 
:- pred example(int::in, int::in, io::di, io::uo) is det.
example(N1, N2, !IO) :-
print(N1, !IO),
print("/", !IO),
print(N2, !IO),
print(" => ", !IO),
print_cf(r2cf_digits(N1, N2), !IO),
nl(!IO).
 
%%%-------------------------------------------------------------------
 
main(!IO) :-
example(1, 2, !IO),
example(3, 1, !IO),
example(23, 8, !IO),
example(13, 11, !IO),
example(22, 7, !IO),
example(-151, 77, !IO),
example(14142, 10000, !IO),
example(141421, 100000, !IO),
example(1414214, 1000000, !IO),
example(14142136, 10000000, !IO),
example(31, 10, !IO),
example(314, 100, !IO),
example(3142, 1000, !IO),
example(31428, 10000, !IO),
example(314285, 100000, !IO),
example(3142857, 1000000, !IO),
example(31428571, 10000000, !IO),
example(314285714, 100000000, !IO),
true.
 
%%%-------------------------------------------------------------------
%%% local variables:
%%% mode: mercury
%%% prolog-indent-width: 2
%%% end:</syntaxhighlight>
 
{{out}}
 
<pre>$ mmc continued_fraction_from_rational.m && ./continued_fraction_from_rational
1/2 => [0; 2]
3/1 => [3]
23/8 => [2; 1, 7]
13/11 => [1; 5, 2]
22/7 => [3; 7]
-151/77 => [-2; 25, 1, 2]
14142/10000 => [1; 2, 2, 2, 2, 2, 1, 1, 29]
141421/100000 => [1; 2, 2, 2, 2, 2, 2, 3, 1, 1, 3, 1, 7, 2]
1414214/1000000 => [1; 2, 2, 2, 2, 2, 2, 2, 3, 6, 1, 2, 1, 12]
14142136/10000000 => [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 1, 2, 4, 1, 1, 2]
31/10 => [3; 10]
314/100 => [3; 7, 7]
3142/1000 => [3; 7, 23, 1, 2]
31428/10000 => [3; 7, 357]
314285/100000 => [3; 7, 2857]
3142857/1000000 => [3; 7, 142857]
31428571/10000000 => [3; 7, 476190, 3]
314285714/100000000 => [3; 7, 7142857]</pre>
 
=={{header|Modula-2}}==
1,448

edits