v / vlib / math / fractions / fraction_test.v
305 lines · 261 sloc · 6.97 KB · c88cc38f4b0cb6160f14c643926176b73ee4becb
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4import math.big
5import math.fractions
6
7// (Old) results are verified using https://www.calculatorsoup.com/calculators/math/fractions.php
8// Newer ones are contrived for corner cases or prepared by hand.
9fn bi(s string) big.Integer {
10 return big.integer_from_string(s) or { panic(err) }
11}
12
13fn test_4_by_8_f64_and_str() {
14 f := fractions.fraction(4, 8)
15 assert f.f64() == 0.5
16 assert f.str() == '4/8'
17}
18
19fn test_10_by_5_f64_and_str() {
20 f := fractions.fraction(10, 5)
21 assert f.f64() == 2.0
22 assert f.str() == '10/5'
23}
24
25fn test_9_by_3_f64_and_str() {
26 f := fractions.fraction(9, 3)
27 assert f.f64() == 3.0
28 assert f.str() == '9/3'
29}
30
31fn test_4_by_minus_5_f64_and_str() {
32 f := fractions.fraction(4, -5)
33 assert f.f64() == -0.8
34 assert f.str() == '-4/5'
35}
36
37fn test_minus_7_by_minus_92_str() {
38 f := fractions.fraction(-7, -5)
39 assert f.str() == '7/5'
40}
41
42fn test_4_by_8_plus_5_by_10() {
43 f1 := fractions.fraction(4, 8)
44 f2 := fractions.fraction(5, 10)
45 sum := f1 + f2
46 assert sum.f64() == 1.0
47 assert sum.str() == '1/1'
48 assert sum == fractions.fraction(1, 1)
49}
50
51fn test_5_by_5_plus_8_by_8() {
52 f1 := fractions.fraction(5, 5)
53 f2 := fractions.fraction(8, 8)
54 sum := f1 + f2
55 assert sum.f64() == 2.0
56 assert sum.str() == '2/1'
57 assert sum == fractions.fraction(2, 1)
58}
59
60fn test_9_by_3_plus_1_by_3() {
61 f1 := fractions.fraction(9, 3)
62 f2 := fractions.fraction(1, 3)
63 sum := f1 + f2
64 assert sum.str() == '10/3'
65 assert sum == fractions.fraction(10, 3)
66}
67
68fn test_3_by_7_plus_1_by_4() {
69 f1 := fractions.fraction(3, 7)
70 f2 := fractions.fraction(1, 4)
71 sum := f1 + f2
72 assert sum.str() == '19/28'
73 assert sum == fractions.fraction(19, 28)
74}
75
76fn test_36529_by_12409100000_plus_418754901_by_9174901000() {
77 f1 := fractions.fraction(i64(36529), i64(12409100000))
78 f2 := fractions.fraction(i64(418754901), i64(9174901000))
79 sum := f1 + f2
80 assert sum.str() == '5196706591957729/113852263999100000'
81}
82
83fn test_4_by_8_plus_minus_5_by_10() {
84 f1 := fractions.fraction(4, 8)
85 f2 := fractions.fraction(-5, 10)
86 diff := f2 + f1
87 assert diff.f64() == 0
88 assert diff.str() == '0/1'
89}
90
91fn test_4_by_8_minus_5_by_10() {
92 f1 := fractions.fraction(4, 8)
93 f2 := fractions.fraction(5, 10)
94 diff := f2 - f1
95 assert diff.f64() == 0
96 assert diff.str() == '0/1'
97}
98
99fn test_5_by_5_minus_8_by_8() {
100 f1 := fractions.fraction(5, 5)
101 f2 := fractions.fraction(8, 8)
102 diff := f2 - f1
103 assert diff.f64() == 0
104 assert diff.str() == '0/1'
105}
106
107fn test_9_by_3_minus_1_by_3() {
108 f1 := fractions.fraction(9, 3)
109 f2 := fractions.fraction(1, 3)
110 diff := f1 - f2
111 assert diff.str() == '8/3'
112}
113
114fn test_3_by_7_minus_1_by_4() {
115 f1 := fractions.fraction(3, 7)
116 f2 := fractions.fraction(1, 4)
117 diff := f1 - f2
118 assert diff.str() == '5/28'
119}
120
121fn test_36529_by_12409100000_minus_418754901_by_9174901000() {
122 f1 := fractions.fraction(i64(36529), i64(12409100000))
123 f2 := fractions.fraction(i64(418754901), i64(9174901000))
124 sum := f1 - f2
125 assert sum.str() == '-5196036292040471/113852263999100000'
126}
127
128fn test_4_by_8_times_5_by_10() {
129 f1 := fractions.fraction(4, 8)
130 f2 := fractions.fraction(5, 10)
131 product := f1 * f2
132 assert product.f64() == 0.25
133 assert product.str() == '1/4'
134}
135
136fn test_5_by_5_times_8_by_8() {
137 f1 := fractions.fraction(5, 5)
138 f2 := fractions.fraction(8, 8)
139 product := f1 * f2
140 assert product.f64() == 1.0
141 assert product.str() == '1/1'
142}
143
144fn test_9_by_3_times_1_by_3() {
145 f1 := fractions.fraction(9, 3)
146 f2 := fractions.fraction(1, 3)
147 product := f1 * f2
148 assert product.f64() == 1.0
149 assert product.str() == '1/1'
150}
151
152fn test_3_by_7_times_1_by_4() {
153 f1 := fractions.fraction(3, 7)
154 f2 := fractions.fraction(1, 4)
155 product := f2 * f1
156 assert product.f64() == (3.0 / 28.0)
157 assert product.str() == '3/28'
158}
159
160fn test_4_by_8_over_5_by_10() {
161 f1 := fractions.fraction(4, 8)
162 f2 := fractions.fraction(5, 10)
163 q := f1 / f2
164 assert q.f64() == 1.0
165 assert q.str() == '1/1'
166}
167
168fn test_5_by_5_over_8_by_8() {
169 f1 := fractions.fraction(5, 5)
170 f2 := fractions.fraction(8, 8)
171 q := f1 / f2
172 assert q.f64() == 1.0
173 assert q.str() == '1/1'
174}
175
176fn test_9_by_3_over_1_by_3() {
177 f1 := fractions.fraction(9, 3)
178 f2 := fractions.fraction(1, 3)
179 q := f1 / f2
180 assert q.f64() == 9.0
181 assert q.str() == '9/1'
182}
183
184fn test_3_by_7_over_1_by_4() {
185 f1 := fractions.fraction(3, 7)
186 f2 := fractions.fraction(1, 4)
187 q := f1 / f2
188 assert q.str() == '12/7'
189}
190
191fn test_reciprocal_4_by_8() {
192 f := fractions.fraction(4, 8)
193 assert f.reciprocal().str() == '8/4'
194}
195
196fn test_reciprocal_5_by_10() {
197 f := fractions.fraction(5, 10)
198 assert f.reciprocal().str() == '10/5'
199}
200
201fn test_reciprocal_5_by_5() {
202 f := fractions.fraction(5, 5)
203 assert f.reciprocal().str() == '5/5'
204}
205
206fn test_reciprocal_8_by_8() {
207 f := fractions.fraction(8, 8)
208 assert f.reciprocal().str() == '8/8'
209}
210
211fn test_reciprocal_9_by_3() {
212 f := fractions.fraction(9, 3)
213 assert f.reciprocal().str() == '3/9'
214}
215
216fn test_reciprocal_1_by_3() {
217 f := fractions.fraction(1, 3)
218 assert f.reciprocal().str() == '3/1'
219}
220
221fn test_reciprocal_7_by_3() {
222 f := fractions.fraction(7, 3)
223 assert f.reciprocal().str() == '3/7'
224}
225
226fn test_reciprocal_1_by_4() {
227 f := fractions.fraction(1, 4)
228 assert f.reciprocal().str() == '4/1'
229}
230
231fn test_4_by_8_equals_5_by_10() {
232 f1 := fractions.fraction(4, 8)
233 f2 := fractions.fraction(5, 10)
234 assert f1 == f2
235}
236
237fn test_1_by_2_does_not_equal_3_by_4() {
238 f1 := fractions.fraction(1, 2)
239 f2 := fractions.fraction(3, 4)
240 assert f1 != f2
241}
242
243fn test_reduce_3_by_9() {
244 f := fractions.fraction(3, 9)
245 assert f.reduce() == fractions.fraction(1, 3)
246}
247
248fn test_1_by_3_less_than_2_by_4() {
249 f1 := fractions.fraction(1, 3)
250 f2 := fractions.fraction(2, 4)
251 assert f1 < f2
252 assert f1 <= f2
253}
254
255fn test_2_by_3_greater_than_2_by_4() {
256 f1 := fractions.fraction(2, 3)
257 f2 := fractions.fraction(2, 4)
258 assert f1 > f2
259 assert f1 >= f2
260}
261
262fn test_5_by_7_not_less_than_2_by_4() {
263 f1 := fractions.fraction(5, 7)
264 f2 := fractions.fraction(2, 4)
265 assert !(f1 < f2)
266 assert !(f1 <= f2)
267}
268
269fn test_49_by_75_not_greater_than_2_by_3() {
270 f1 := fractions.fraction(49, 75)
271 f2 := fractions.fraction(2, 3)
272 assert !(f1 > f2)
273 assert !(f1 >= f2)
274}
275
276fn test_i32_rational_addition() {
277 f1 := fractions.rational(i32(4), i32(8))
278 f2 := fractions.rational(i32(5), i32(10))
279 sum := f1 + f2
280 assert sum.str() == '1/1'
281 assert sum == fractions.rational(i32(1), i32(1))
282}
283
284fn test_big_fraction_normalizes_and_reduces() {
285 f := fractions.big_fraction(bi('-14'), bi('-21'))
286 assert f.str() == '14/21'
287 assert f.reciprocal().str() == '21/14'
288 assert f.reduce().str() == '2/3'
289}
290
291fn test_big_fraction_addition() {
292 f1 := fractions.big_fraction(bi('100000000000000000000000000000000000000'), bi('3'))
293 f2 := fractions.big_fraction(bi('5'), bi('6'))
294 sum := f1 + f2
295 assert sum.str() == '200000000000000000000000000000000000005/6'
296 assert sum > f1
297}
298
299fn test_big_fraction_exact_comparison_beyond_i64() {
300 huge := bi('9223372036854775808123456789')
301 f1 := fractions.big_fraction(huge + big.one_int, huge)
302 f2 := fractions.big_fraction(huge, huge + big.one_int)
303 assert f1 > f2
304 assert f1 != f2
305}
306