Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 55.6% 5 / 0 / 9
Functions: -% 0 / 1 / 1
Branches: 30.0% 6 / 0 / 20

OMCompiler/Compiler/Util/Rational.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated uniontype Rational
37
38 protected
39 import Util;
40
41 public
42 record RATIONAL
43 Integer n "numerator";
44 Integer d "denominator";
45 end RATIONAL;
46
47 constant Rational ZERO = RATIONAL(0, 1);
48 constant Rational ONE = RATIONAL(1, 1);
49
50 function isEqual
51 input Rational r1;
52 input Rational r2;
53 output Boolean b = r1.n == r2.n and r1.d == r2.d;
54 end isEqual;
55
56 function compare "Compares two rationals and return -1 if the first is smallest, 1 if the second is smallest, or 0 if they are equal."
57 input Rational r1;
58 input Rational r2;
59 output Integer i;
60 protected
61 // Divide by common divisors to avoid overflow
62 Integer gn = Util.gcd(r1.n, r2.n);
63 Integer gd = Util.gcd(r1.d, r2.d);
64 algorithm
65 ✗ i := Util.intCompare(intDiv(r1.n, gn)*intDiv(r2.d, gd), intDiv(r2.n, gn)*intDiv(r1.d, gd));
66 end compare;
67
68 function toString
69 input Rational r;
70 output String str = intString(r.n) + "/" + intString(r.d);
71 end toString;
72
73 function normalize
74 input output Rational r;
75 algorithm
76
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 28 times.
54 if r.n == 0 then
77 26 r.d := 1;
78 elseif r.d < 0 then
79 ✗ r := RATIONAL(-r.n, -r.d);
80 end if;
81 end normalize;
82
83 function add "a/b + c/d = (ad + bc)/(bd) = (a(d/g) + (b/g)c)/((b/g)d)"
84 input Rational r1;
85 input Rational r2;
86 output Rational r;
87 protected
88 Integer g = Util.gcd(r1.d, r2.d);
89 algorithm
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 r := reduce(r1.n*intDiv(r2.d, g) + intDiv(r1.d, g)*r2.n, intDiv(r1.d,g)*r2.d);
91 end add;
92
93 function neg "-(a/b) = (-a)/b"
94 input Rational r;
95 output Rational s = RATIONAL(-r.n, r.d);
96 end neg;
97
98 function sub "a/b - c/d = (ad - bc)/(bd) = (a(d/g) - (b/g)c)/((b/g)d)"
99 input Rational r1;
100 input Rational r2;
101 output Rational r;
102 protected
103 Integer g = Util.gcd(r1.d, r2.d);
104 algorithm
105 ✗ r := reduce(r1.n*intDiv(r2.d, g) - intDiv(r1.d, g)*r2.n, intDiv(r1.d,g)*r2.d);
106 end sub;
107
108 function mul "a/b * c/d = (ac)/(bd) = ((a/g1)(c/g2))/((b/g2)(d/g1))"
109 input Rational r1;
110 input Rational r2;
111 output Rational r;
112 protected
113 Integer g1 = Util.gcd(r1.n, r2.d);
114 Integer g2 = Util.gcd(r2.n, r1.d);
115 algorithm
116
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
36 r := reduce(intDiv(r1.n, g1)*intDiv(r2.n, g2), intDiv(r1.d, g2)*intDiv(r2.d, g1));
117 end mul;
118
119 function inv "(a/b)^(-1) = b/a"
120 input Rational r;
121 output Rational s = RATIONAL(Util.intSign(r.n)*r.d, intAbs(r.n));
122 end inv;
123
124 function div "(a/b) / (c/d) = (ad)/(bc) = ((a/g1)(d/g2))/((b/g2)(c/g1))"
125 input Rational r1;
126 input Rational r2;
127 output Rational r;
128 protected
129 Integer g1 = Util.gcd(r1.n, r2.n);
130 Integer g2 = Util.gcd(r2.d, r1.d);
131 algorithm
132 ✗ r := reduce(intDiv(r1.n, g1)*intDiv(r2.d, g2), intDiv(r1.d, g2)*intDiv(r2.n, g1));
133 end div;
134
135 protected
136 function reduce
137 input Integer i1;
138 input Integer i2;
139 output Rational r;
140 protected
141 Integer d = Util.gcd(i1, i2);
142 algorithm
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 r := normalize(RATIONAL(intDiv(i1, d), intDiv(i2, d)));
144 end reduce;
145 annotation(__OpenModelica_Interface="util");
146 end Rational;
147