Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 73.0% 27 / 0 / 37
Functions: -% 0 / 1 / 1
Branches: 10.0% 4 / 0 / 40

OMCompiler/Compiler/FrontEnd/MMath.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 package MMath
37 " file: MMath.mo
38 package: MMath
39 description: Rational numbers and operations
40 @author: Peter Aronsson (peter.aronsson@mathcore.com)
41
42 $Id$
43 "
44 public
45 uniontype Rational
46 record RATIONAL "represents a rational number, e.g. 6/7"
47 Integer nom "numerator";
48 Integer denom "denominator";
49 end RATIONAL;
50 end Rational;
51
52 public constant Rational RAT0 = RATIONAL(0, 1);
53 public constant Rational RAT1 = RATIONAL(1, 1);
54
55 public function isGreaterThan "comparison if greater than"
56 input Rational r1;
57 input Rational r2;
58 output Boolean b;
59 algorithm
60 ✗ b := realGt(r1.nom/r1.denom, r2.nom/r2.denom);
61 end isGreaterThan;
62
63 public function addRational "adds two rationals"
64 input Rational r1;
65 input Rational r2;
66 output Rational r;
67 algorithm
68 r := match(r1,r2)
69 local Integer i1,i2,i3,i4,ri1,ri2,d;
70 case(RATIONAL(i1,i2),RATIONAL(i3,i4)) algorithm
71 17 ri1 := i1*i4 + i3*i2;
72 17 ri2 := i2*i4;
73 17 d := intGcd(ri1,ri2);
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 ri1 := intDiv(ri1, d);
75 17 ri2 := intDiv(ri2, d);
76 17 then normalizeZero(RATIONAL(ri1,ri2));
77 end match;
78 end addRational;
79
80 protected function normalizeZero "if numerator is zero, set denominator to 1"
81 input Rational r;
82 output Rational outR;
83 algorithm
84 outR := match r
85 case RATIONAL(0,_) then RATIONAL(0,1);
86 else r;
87 end match;
88 end normalizeZero;
89
90 public function rationalString "converts a rational to a string"
91 input Rational r;
92 output String str;
93 algorithm
94 str := match r
95 local Integer n,d;
96 case RATIONAL(n,d) algorithm
97 24 str := intString(n)+"/"+intString(d);
98 then str;
99 end match;
100 end rationalString;
101
102 public function equals
103 input Rational r1;
104 input Rational r2;
105 output Boolean res;
106 algorithm
107 res := match (r1, r2)
108 local
109 Integer i1, i2, i3, i4;
110 case (RATIONAL(i1,i2), RATIONAL(i3,i4))
111 121 then i1*i4 - i3*i2 == 0;
112 end match;
113 end equals;
114
115 public function subRational "subtracts two rationals"
116 input Rational r1;
117 input Rational r2;
118 output Rational r;
119 algorithm
120 r := match(r1,r2)
121 local Integer i1,i2,i3,i4,ri1,ri2,d;
122 case(RATIONAL(i1,i2),RATIONAL(i3,i4)) algorithm
123 8 ri1 := i1*i4 - i3*i2;
124 8 ri2 := i2*i4;
125 8 d := intGcd(ri1,ri2);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 ri1 := intDiv(ri1, d);
127 8 ri2 := intDiv(ri2, d);
128 8 then normalizeZero(RATIONAL(ri1,ri2));
129 end match;
130 end subRational;
131
132 public function multRational "multiply two rationals"
133 input Rational r1;
134 input Rational r2;
135 output Rational r;
136 algorithm
137 r := match(r1,r2)
138 local Integer i1,i2,i3,i4,ri1,ri2,d;
139 case(RATIONAL(i1,i2),RATIONAL(i3,i4)) algorithm
140 17 ri1 := i1*i3;
141 17 ri2 := i2*i4;
142 17 d := intGcd(ri1,ri2);
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 ri1 := intDiv(ri1,d);
144 17 ri2 := intDiv(ri2,d);
145 17 then normalizeZero(RATIONAL(ri1,ri2));
146 end match;
147 end multRational;
148
149 public function divRational "division of two rationals i1/i2 / i3/i4 = (i1*i4) / (i3*i2) "
150 input Rational r1;
151 input Rational r2;
152 output Rational r;
153 algorithm
154 r := match(r1,r2)
155 local Integer i1,i2,i3,i4,ri1,ri2,d;
156 case(RATIONAL(i1,i2),RATIONAL(i3,i4)) algorithm
157 30 ri1 := i1*i4;
158 30 ri2 := i3*i2;
159 30 d := intGcd(ri1,ri2);
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 ri1 := intDiv(ri1, d);
161 30 ri2 := intDiv(ri2, d);
162 30 then normalizeZero(RATIONAL(ri1,ri2));
163 end match;
164 end divRational;
165
166 public function intGcd "returns the greatest common divisor for two Integers"
167 input Integer i1;
168 input Integer i2;
169 output Integer i;
170 algorithm
171 i := match i2
172 case 0 then i1;
173 103 else intGcd(i2,intMod(i1,i2));
174 end match;
175 end intGcd;
176
177 /* Tests */
178
179 public function testRational "test rational operators"
180 algorithm
181 () := matchcontinue()
182
183 case() algorithm
184 ✗ RATIONAL(7,6) := addRational(RATIONAL(1,2),RATIONAL(2,3));
185 ✗ RATIONAL(2,1) := addRational(RATIONAL(1,2),RATIONAL(3,2));
186
187 ✗ RATIONAL(1,1) := subRational(RATIONAL(3,2),RATIONAL(1,2));
188 ✗ RATIONAL(1,3) := subRational(RATIONAL(1,2),RATIONAL(1,6));
189
190 ✗ RATIONAL(4,3) := multRational(RATIONAL(2,3),RATIONAL(4,2));
191 ✗ RATIONAL(1,1) := multRational(RATIONAL(1,1),RATIONAL(1,1));
192
193 ✗ RATIONAL(1,2) := divRational(RATIONAL(1,3),RATIONAL(2,3));
194 ✗ print("testRational succeeded\n");
195 then ();
196 else algorithm
197 ✗ print("testRationals failed\n");
198 then ();
199
200 end matchcontinue;
201 end testRational;
202
203 annotation(__OpenModelica_Interface="util");
204 end MMath;
205