Rational numbers in Erlang
rebar3 compile
rebar3 check1> Third = rationals:new(1, 3).
{fraction,1,3}
2> Quarter = rationals:new(1, 4).
{fraction,1,4}3> rationals:numerator(Quarter).
1
4> rationals:denominator(Quarter).
45> rationals:add(Quarter, Third).
{fraction,7,12}
6> rationals:multiply(Quarter, Third).
{fraction,1,12}Arithmetic returns unreduced fractions; call reduce/1 (or normalize/1) for
canonical form — reduced to lowest terms with the sign on the numerator and a
positive denominator:
7> Sum = rationals:add(rationals:new(3, 4), rationals:new(5, 12)).
{fraction,56,48}
8> rationals:reduce(Sum).
{fraction,7,6}
9> rationals:normalize(rationals:new(1, -2)).
{fraction,-1,2}The constants zero/0 and one/0 return canonical 0/1 and 1/1:
10> rationals:zero().
{fraction,0,1}
11> rationals:one().
{fraction,1,1}Compare fractions by value with compare/2 (which returns lt, eq, or gt) or with the boolean predicates gt/2, lt/2, eq/2, gte/2, and lte/2:
12> rationals:compare(Quarter, Third).
lt
13> rationals:gt(Third, Quarter).
true
14> rationals:eq(rationals:new(2, 4), rationals:new(1, 2)).
trueNegate, absolute value, and sign:
15> rationals:negate(Quarter).
{fraction,-1,4}
16> rationals:abs(rationals:new(-3, 4)).
{fraction,3,4}
17> rationals:sign(rationals:new(-3, 4)).
-1Integer exponentiation, sum, and product:
18> rationals:pow(rationals:new(2, 3), 3).
{fraction,8,27}
19> rationals:pow(rationals:new(2, 3), -1).
{fraction,3,2}
20> rationals:sum([rationals:new(1, 2), rationals:new(1, 3), rationals:new(1, 6)]).
{fraction,6,6}
21> rationals:reduce(rationals:sum([rationals:new(1, 2), rationals:new(1, 3), rationals:new(1, 6)])).
{fraction,1,1}
22> rationals:product([rationals:new(2, 3), rationals:new(3, 4)]).
{fraction,6,12}Rounding and integer conversion — floor/1 rounds toward −∞, ceil/1 toward
+∞, truncate/1 toward zero, and round/1 rounds half away from zero:
23> rationals:floor(rationals:new(-7, 2)).
-4
24> rationals:ceil(rationals:new(-7, 2)).
-3
25> rationals:round(rationals:new(5, 2)).
3Mixed-number decomposition and predicates:
26> rationals:to_mixed(rationals:new(7, 3)).
{2,{fraction,1,3}}
27> rationals:from_mixed(2, 1, 3).
{fraction,7,3}
28> rationals:is_integer(rationals:new(6, 3)).
true
29> rationals:is_proper(rationals:new(3, 4)).
trueParse fractions from text and format them as binaries:
30> rationals:parse("3/4").
{ok,{fraction,3,4}}
31> rationals:parse("-7/3").
{ok,{fraction,-7,3}}
32> rationals:parse("42").
{ok,{fraction,42,1}}
33> rationals:parse("3/0").
{error,zero_denominator}
34> rationals:format(rationals:new(7, 12)).
<<"7/12">>
35> rationals:format(rationals:new(3, 1)).
<<"3">>
36> rationals:from_integer(5).
{fraction,5,1}Continued fractions, convergents, and best rational approximation:
37> rationals:continued_fraction(rationals:new(7, 3)).
[2,3]
38> rationals:convergents(rationals:new(7, 3)).
[{fraction,2,1},{fraction,7,3}]
39> rationals:rationalize(3.14159, 0.001).
{fraction,22,7}
40> rationals:mediant(rationals:new(1, 2), rationals:new(1, 3)).
{fraction,2,5}Exact decimal expansion (non-repeating + repeating block):
41> rationals:decimal_expansion(rationals:new(1, 6)).
{<<"0.1">>,<<"6">>}
42> rationals:decimal_expansion(rationals:new(2, 7)).
{<<"0.">>,<<"285714">>}Egyptian fraction decomposition and Farey sequences:
43> rationals:egyptian(rationals:new(2, 3)).
[{fraction,1,2},{fraction,1,6}]
44> rationals:farey(3).
[{fraction,0,1},{fraction,1,3},{fraction,1,2},{fraction,2,3},{fraction,1,1}]Also available: min/2, max/2, clamp/3, between/3, dist/2,
is_zero/1, is_positive/1, is_negative/1, is_reduced/1,
is_unit_fraction/1, lcm/2, from_continued_fraction/1.
23> rationals:gcd(64, 72).
8The original long-form names — simplify/1, is_greater_than/2, is_less_than/2, is_equal_to/2, is_greater_or_equal/2, and is_less_or_equal/2 — remain available as backward-compatible aliases, but the short names above are preferred.
See more examples in test/rationals_SUITE.erl; see rationals.erl for implementation details.
reduce/1 (and its alias simplify/1) now canonicalize sign: the denominator
is always positive in the result and the sign is carried on the numerator.
Previously, reduce(new(1, -2)) returned 1/-2; it now returns -1/2.
compare/2 and all derived predicates are now sign-robust — they normalize
operands internally, so comparisons are correct even on fractions with a
negative denominator.
Copyright © 2021-2026, Erlang-Aided Enrichment Center
Copyright © 2014 Peter Morgan peter.james.morgan@gmail.com
