2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 private unit private.rational;
21 fn rational_zero : rational;
22 fn rational_one : rational;
23 fn rational_pi : rational;
24 fn rational_neg(i1 : rational) : rational;
25 fn rational_add(i1 i2 : rational) : rational;
26 fn rational_subtract(i1 i2 : rational) : rational;
27 fn rational_multiply(i1 i2 : rational) : rational;
28 fn rational_recip(i1 : rational) : rational;
29 fn rational_divide(i1 i2 : rational) : rational;
30 fn rational_modulo(i1 i2 : rational) : rational;
31 fn rational_power(i1 i2 : rational) : rational;
32 fn rational_ldexp(i1 i2 : rational) : rational;
33 fn rational_atan2(i1 i2 : rational) : rational;
34 fn rational_sqrt(i1 : rational) : rational;
35 fn rational_cbrt(i1 : rational) : rational;
36 fn rational_sin(i1 : rational) : rational;
37 fn rational_cos(i1 : rational) : rational;
38 fn rational_tan(i1 : rational) : rational;
39 fn rational_asin(i1 : rational) : rational;
40 fn rational_acos(i1 : rational) : rational;
41 fn rational_atan(i1 : rational) : rational;
42 fn rational_sinh(i1 : rational) : rational;
43 fn rational_cosh(i1 : rational) : rational;
44 fn rational_tanh(i1 : rational) : rational;
45 fn rational_asinh(i1 : rational) : rational;
46 fn rational_acosh(i1 : rational) : rational;
47 fn rational_atanh(i1 : rational) : rational;
48 fn rational_log2(i1 : rational) : rational;
49 fn rational_log(i1 : rational) : rational;
50 fn rational_log10(i1 : rational) : rational;
51 fn rational_exp2(i1 : rational) : rational;
52 fn rational_exp(i1 : rational) : rational;
53 fn rational_exp10(i1 : rational) : rational;
54 fn rational_round(i1 : rational) : rational;
55 fn rational_ceil(i1 : rational) : rational;
56 fn rational_floor(i1 : rational) : rational;
57 fn rational_trunc(i1 : rational) : rational;
58 fn rational_fract(i1 : rational) : rational;
59 fn rational_mantissa(i1 : rational) : rational;
60 fn rational_exponent(i1 : rational) : rational;
61 fn rational_next_number(i1 : rational) : rational;
62 fn rational_prev_number(i1 : rational) : rational;
63 fn rational_is_negative(i1 : rational) : bool;
64 fn rational_is_infinity(i1 : rational) : bool;
65 fn rational_equal(i1 i2 : rational) : bool;
66 fn rational_less(i1 i2 : rational) : bool;
67 fn rational_to_int(i1 : rational) : int;
68 fn rational_from_int(i1 : int) : rational;
69 fn rational_to_bytes(i1 : rational) : bytes;
70 fn rational_to_bytes_base_precision(i1 : rational, b : int, digits : int) : bytes;
71 fn rational_from_bytes(a1 : bytes) : rational;
72 fn rational_from_bytes_base(a1 : bytes, b : int) : rational;
79 fn gcd(a b : int) : int
88 fn rational_normalize(i : rational) : rational
92 abort exception_make(rational, ec_sync, error_nan, 0, true);
99 var g := gcd(i.num, i.den);
102 if i.den < 0 and i.num <> 0 then [
109 fn rational_zero : rational
111 return rational.[ num : 0, den : 1 ];
114 fn rational_one : rational
116 return rational.[ num : 1, den : 1 ];
119 fn rational_pi : rational
121 return instance_real_number_real64.pi;
124 fn rational_neg(i1 : rational) : rational
137 fn rational_add(i1 i2 : rational) : rational
140 num : i1.num * i2.den + i1.den * i2.num,
141 den : i1.den * i2.den,
143 return rational_normalize(r);
146 fn rational_subtract(i1 i2 : rational) : rational
149 num : i1.num * i2.den - i1.den * i2.num,
150 den : i1.den * i2.den,
152 return rational_normalize(r);
155 fn rational_multiply(i1 i2 : rational) : rational
158 num : i1.num * i2.num,
159 den : i1.den * i2.den,
161 return rational_normalize(r);
164 fn rational_recip(i1 : rational) : rational
173 fn rational_divide(i1 i2 : rational) : rational
176 num : i1.num * i2.den,
177 den : i1.den * i2.num,
179 return rational_normalize(r);
182 fn rational_modulo(i1 i2 : rational) : rational
184 var r := trunc(i1 / i2);
188 fn rational_power(i1 i2 : rational) : rational
191 i1.num := ipower(i1.num, i2.num);
192 i1.den := ipower(i1.den, i2.num);
195 var r1 : real64 := i1;
196 var r2 : real64 := i2;
197 return power(r1, r2);
200 fn rational_ldexp(i1 i2 : rational) : rational
203 if i2.num >= 0 then [
205 return rational_normalize(i1);
208 return rational_normalize(i1);
211 var r1 : real64 := i1;
212 var r2 : real64 := i2;
213 return ldexp(r1, r2);
216 fn rational_atan2(i1 i2 : rational) : rational
218 var r1 : real64 := i1;
219 var r2 : real64 := i2;
220 return atan2(r1, r2);
223 fn rational_sqrt(i1 : rational) : rational [ var r : real64 := i1; return sqrt(r); ]
224 fn rational_cbrt(i1 : rational) : rational [ var r : real64 := i1; return cbrt(r); ]
225 fn rational_sin(i1 : rational) : rational [ var r : real64 := i1; return sin(r); ]
226 fn rational_cos(i1 : rational) : rational [ var r : real64 := i1; return cos(r); ]
227 fn rational_tan(i1 : rational) : rational [ var r : real64 := i1; return tan(r); ]
228 fn rational_asin(i1 : rational) : rational [ var r : real64 := i1; return asin(r); ]
229 fn rational_acos(i1 : rational) : rational [ var r : real64 := i1; return acos(r); ]
230 fn rational_atan(i1 : rational) : rational [ var r : real64 := i1; return atan(r); ]
231 fn rational_sinh(i1 : rational) : rational [ var r : real64 := i1; return sinh(r); ]
232 fn rational_cosh(i1 : rational) : rational [ var r : real64 := i1; return cosh(r); ]
233 fn rational_tanh(i1 : rational) : rational [ var r : real64 := i1; return tanh(r); ]
234 fn rational_asinh(i1 : rational) : rational [ var r : real64 := i1; return asinh(r); ]
235 fn rational_acosh(i1 : rational) : rational [ var r : real64 := i1; return acosh(r); ]
236 fn rational_atanh(i1 : rational) : rational [ var r : real64 := i1; return atanh(r); ]
237 fn rational_log2(i1 : rational) : rational [ var r : real64 := i1; return log2(r); ]
238 fn rational_log(i1 : rational) : rational [ var r : real64 := i1; return log(r); ]
239 fn rational_log10(i1 : rational) : rational [ var r : real64 := i1; return log10(r); ]
240 fn rational_exp2(i1 : rational) : rational [ var r : real64 := i1; return exp2(r); ]
241 fn rational_exp(i1 : rational) : rational [ var r : real64 := i1; return exp(r); ]
242 fn rational_exp10(i1 : rational) : rational [ var r : real64 := i1; return exp10(r); ]
244 fn rational_round(i1 : rational) : rational
246 if abs(rational_fract(i1)) = 0.5 then [
248 if i bt 0 = is_negative i1 then
249 return i - (i and 1);
251 return rational_floor(i1 + 0.5);
254 fn rational_ceil(i1 : rational) : rational
262 fn rational_floor(i1 : rational) : rational
270 fn rational_trunc(i1 : rational) : rational
276 fn rational_fract(i1 : rational) : rational
278 var r := rational_trunc(i1);
282 fn rational_mantissa(i1 : rational) : rational [ var r : real64 := i1; return mantissa(r); ]
283 fn rational_exponent(i1 : rational) : rational [ var r : real64 := i1; return exponent(r); ]
284 fn rational_next_number(i1 : rational) : rational [ var r : real64 := i1; return next_number(r); ]
285 fn rational_prev_number(i1 : rational) : rational [ var r : real64 := i1; return prev_number(r); ]
287 fn rational_is_negative(i1 : rational) : bool
294 fn rational_is_infinity(i1 : rational) : bool
299 fn rational_equal(i1 i2 : rational) : bool
301 return i1.num * i2.den = i1.den * i2.num;
304 fn rational_less(i1 i2 : rational) : bool
306 return i1.num * i2.den < i1.den * i2.num;
309 fn rational_to_int(i1 : rational) : int
312 abort exception_make(int, ec_sync, error_infinity, 0, true);
313 return i1.num div i1.den;
316 fn rational_from_int(i1 : int) : rational
324 fn rational_to_bytes(i1 : rational) : bytes
326 return real_to_bytes(i1);
329 fn rational_to_bytes_base_precision(i1 : rational, b : int, digits : int) : bytes
331 return real_to_bytes_base_precision(i1, b, digits);
334 fn rational_from_bytes(a1 : bytes) : rational
336 return bytes_to_real(rational, instance_real_number_rational, a1);
339 fn rational_from_bytes_base(a1 : bytes, b : int) : rational
341 return bytes_to_real_base(rational, instance_real_number_rational, a1, b);