1 """Tests for Lib/fractions.py."""
3 from decimal
import Decimal
4 from test
.test_support
import run_unittest
9 from copy
import copy
, deepcopy
10 from cPickle
import dumps
, loads
11 F
= fractions
.Fraction
15 class GcdTest(unittest
.TestCase
):
18 self
.assertEquals(0, gcd(0, 0))
19 self
.assertEquals(1, gcd(1, 0))
20 self
.assertEquals(-1, gcd(-1, 0))
21 self
.assertEquals(1, gcd(0, 1))
22 self
.assertEquals(-1, gcd(0, -1))
23 self
.assertEquals(1, gcd(7, 1))
24 self
.assertEquals(-1, gcd(7, -1))
25 self
.assertEquals(1, gcd(-23, 15))
26 self
.assertEquals(12, gcd(120, 84))
27 self
.assertEquals(-12, gcd(84, -120))
31 return (r
.numerator
, r
.denominator
)
34 class FractionTest(unittest
.TestCase
):
36 def assertTypedEquals(self
, expected
, actual
):
37 """Asserts that both the types and values are the same."""
38 self
.assertEquals(type(expected
), type(actual
))
39 self
.assertEquals(expected
, actual
)
41 def assertRaisesMessage(self
, exc_type
, message
,
42 callable, *args
, **kwargs
):
43 """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
45 callable(*args
, **kwargs
)
47 self
.assertEquals(message
, str(e
))
49 self
.fail("%s not raised" % exc_type
.__name
__)
52 self
.assertEquals((0, 1), _components(F()))
53 self
.assertEquals((7, 1), _components(F(7)))
54 self
.assertEquals((7, 3), _components(F(F(7, 3))))
56 self
.assertEquals((-1, 1), _components(F(-1, 1)))
57 self
.assertEquals((-1, 1), _components(F(1, -1)))
58 self
.assertEquals((1, 1), _components(F(-2, -2)))
59 self
.assertEquals((1, 2), _components(F(5, 10)))
60 self
.assertEquals((7, 15), _components(F(7, 15)))
61 self
.assertEquals((10**23, 1), _components(F(10**23)))
63 self
.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
65 self
.assertRaises(TypeError, F
, 1.5)
66 self
.assertRaises(TypeError, F
, 1.5 + 3j
)
68 self
.assertRaises(TypeError, F
, F(1, 2), 3)
69 self
.assertRaises(TypeError, F
, "3/2", 3)
71 def testFromString(self
):
72 self
.assertEquals((5, 1), _components(F("5")))
73 self
.assertEquals((3, 2), _components(F("3/2")))
74 self
.assertEquals((3, 2), _components(F(" \n +3/2")))
75 self
.assertEquals((-3, 2), _components(F("-3/2 ")))
76 self
.assertEquals((13, 2), _components(F(" 013/02 \n ")))
77 self
.assertEquals((13, 2), _components(F(u
" 013/02 \n ")))
79 self
.assertEquals((16, 5), _components(F(" 3.2 ")))
80 self
.assertEquals((-16, 5), _components(F(u
" -3.2 ")))
81 self
.assertEquals((-3, 1), _components(F(u
" -3. ")))
82 self
.assertEquals((3, 5), _components(F(u
" .6 ")))
85 self
.assertRaisesMessage(
86 ZeroDivisionError, "Fraction(3, 0)",
88 self
.assertRaisesMessage(
89 ValueError, "Invalid literal for Fraction: '3/'",
91 self
.assertRaisesMessage(
92 ValueError, "Invalid literal for Fraction: '3 /2'",
94 self
.assertRaisesMessage(
95 # Denominators don't need a sign.
96 ValueError, "Invalid literal for Fraction: '3/+2'",
98 self
.assertRaisesMessage(
99 # Imitate float's parsing.
100 ValueError, "Invalid literal for Fraction: '+ 3/2'",
102 self
.assertRaisesMessage(
103 # Avoid treating '.' as a regex special character.
104 ValueError, "Invalid literal for Fraction: '3a2'",
106 self
.assertRaisesMessage(
107 # Only parse ordinary decimals, not scientific form.
108 ValueError, "Invalid literal for Fraction: '3.2e4'",
110 self
.assertRaisesMessage(
111 # Don't accept combinations of decimals and fractions.
112 ValueError, "Invalid literal for Fraction: '3/7.2'",
114 self
.assertRaisesMessage(
115 # Don't accept combinations of decimals and fractions.
116 ValueError, "Invalid literal for Fraction: '3.2/7'",
118 self
.assertRaisesMessage(
119 # Allow 3. and .3, but not .
120 ValueError, "Invalid literal for Fraction: '.'",
123 def testImmutable(self
):
126 self
.assertEquals((7, 3), _components(r
))
128 self
.assertRaises(AttributeError, setattr, r
, 'numerator', 12)
129 self
.assertRaises(AttributeError, setattr, r
, 'denominator', 6)
130 self
.assertEquals((7, 3), _components(r
))
132 # But if you _really_ need to:
135 self
.assertEquals((4, 2), _components(r
))
136 # Which breaks some important operations:
137 self
.assertNotEquals(F(4, 2), r
)
139 def testFromFloat(self
):
140 self
.assertRaises(TypeError, F
.from_float
, 3+4j
)
141 self
.assertEquals((10, 1), _components(F
.from_float(10)))
142 self
.assertEquals((0, 1), _components(F
.from_float(-0.0)))
143 self
.assertEquals((10, 1), _components(F
.from_float(10.0)))
144 self
.assertEquals((-5, 2), _components(F
.from_float(-2.5)))
145 self
.assertEquals((99999999999999991611392, 1),
146 _components(F
.from_float(1e23
)))
147 self
.assertEquals(float(10**23), float(F
.from_float(1e23
)))
148 self
.assertEquals((3602879701896397, 1125899906842624),
149 _components(F
.from_float(3.2)))
150 self
.assertEquals(3.2, float(F
.from_float(3.2)))
154 self
.assertRaisesMessage(
155 TypeError, "Cannot convert inf to Fraction.",
157 self
.assertRaisesMessage(
158 TypeError, "Cannot convert -inf to Fraction.",
160 self
.assertRaisesMessage(
161 TypeError, "Cannot convert nan to Fraction.",
164 def testFromDecimal(self
):
165 self
.assertRaises(TypeError, F
.from_decimal
, 3+4j
)
166 self
.assertEquals(F(10, 1), F
.from_decimal(10))
167 self
.assertEquals(F(0), F
.from_decimal(Decimal("-0")))
168 self
.assertEquals(F(5, 10), F
.from_decimal(Decimal("0.5")))
169 self
.assertEquals(F(5, 1000), F
.from_decimal(Decimal("5e-3")))
170 self
.assertEquals(F(5000), F
.from_decimal(Decimal("5e3")))
171 self
.assertEquals(1 - F(1, 10**30),
172 F
.from_decimal(Decimal("0." + "9" * 30)))
174 self
.assertRaisesMessage(
175 TypeError, "Cannot convert Infinity to Fraction.",
176 F
.from_decimal
, Decimal("inf"))
177 self
.assertRaisesMessage(
178 TypeError, "Cannot convert -Infinity to Fraction.",
179 F
.from_decimal
, Decimal("-inf"))
180 self
.assertRaisesMessage(
181 TypeError, "Cannot convert NaN to Fraction.",
182 F
.from_decimal
, Decimal("nan"))
183 self
.assertRaisesMessage(
184 TypeError, "Cannot convert sNaN to Fraction.",
185 F
.from_decimal
, Decimal("snan"))
187 def testLimitDenominator(self
):
188 rpi
= F('3.1415926535897932')
189 self
.assertEqual(rpi
.limit_denominator(10000), F(355, 113))
190 self
.assertEqual(-rpi
.limit_denominator(10000), F(-355, 113))
191 self
.assertEqual(rpi
.limit_denominator(113), F(355, 113))
192 self
.assertEqual(rpi
.limit_denominator(112), F(333, 106))
193 self
.assertEqual(F(201, 200).limit_denominator(100), F(1))
194 self
.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
195 self
.assertEqual(F(0).limit_denominator(10000), F(0))
197 def testConversions(self
):
198 self
.assertTypedEquals(-1, math
.trunc(F(-11, 10)))
199 self
.assertTypedEquals(-1, int(F(-11, 10)))
201 self
.assertEquals(False, bool(F(0, 1)))
202 self
.assertEquals(True, bool(F(3, 2)))
203 self
.assertTypedEquals(0.1, float(F(1, 10)))
205 # Check that __float__ isn't implemented by converting the
206 # numerator and denominator to float before dividing.
207 self
.assertRaises(OverflowError, float, long('2'*400+'7'))
208 self
.assertAlmostEquals(2.0/3,
209 float(F(long('2'*400+'7'), long('3'*400+'1'))))
211 self
.assertTypedEquals(0.1+0j
, complex(F(1,10)))
214 def testArithmetic(self
):
215 self
.assertEquals(F(1, 2), F(1, 10) + F(2, 5))
216 self
.assertEquals(F(-3, 10), F(1, 10) - F(2, 5))
217 self
.assertEquals(F(1, 25), F(1, 10) * F(2, 5))
218 self
.assertEquals(F(1, 4), F(1, 10) / F(2, 5))
219 self
.assertTypedEquals(2, F(9, 10) // F(2, 5))
220 self
.assertTypedEquals(10**23, F(10**23, 1) // F(1))
221 self
.assertEquals(F(2, 3), F(-7, 3) % F(3, 2))
222 self
.assertEquals(F(8, 27), F(2, 3) ** F(3))
223 self
.assertEquals(F(27, 8), F(2, 3) ** F(-3))
224 self
.assertTypedEquals(2.0, F(4) ** F(1, 2))
225 # Will return 1j in 3.0:
226 self
.assertRaises(ValueError, pow, F(-1), F(1, 2))
228 def testMixedArithmetic(self
):
229 self
.assertTypedEquals(F(11, 10), F(1, 10) + 1)
230 self
.assertTypedEquals(1.1, F(1, 10) + 1.0)
231 self
.assertTypedEquals(1.1 + 0j
, F(1, 10) + (1.0 + 0j
))
232 self
.assertTypedEquals(F(11, 10), 1 + F(1, 10))
233 self
.assertTypedEquals(1.1, 1.0 + F(1, 10))
234 self
.assertTypedEquals(1.1 + 0j
, (1.0 + 0j
) + F(1, 10))
236 self
.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
237 self
.assertTypedEquals(-0.9, F(1, 10) - 1.0)
238 self
.assertTypedEquals(-0.9 + 0j
, F(1, 10) - (1.0 + 0j
))
239 self
.assertTypedEquals(F(9, 10), 1 - F(1, 10))
240 self
.assertTypedEquals(0.9, 1.0 - F(1, 10))
241 self
.assertTypedEquals(0.9 + 0j
, (1.0 + 0j
) - F(1, 10))
243 self
.assertTypedEquals(F(1, 10), F(1, 10) * 1)
244 self
.assertTypedEquals(0.1, F(1, 10) * 1.0)
245 self
.assertTypedEquals(0.1 + 0j
, F(1, 10) * (1.0 + 0j
))
246 self
.assertTypedEquals(F(1, 10), 1 * F(1, 10))
247 self
.assertTypedEquals(0.1, 1.0 * F(1, 10))
248 self
.assertTypedEquals(0.1 + 0j
, (1.0 + 0j
) * F(1, 10))
250 self
.assertTypedEquals(F(1, 10), F(1, 10) / 1)
251 self
.assertTypedEquals(0.1, F(1, 10) / 1.0)
252 self
.assertTypedEquals(0.1 + 0j
, F(1, 10) / (1.0 + 0j
))
253 self
.assertTypedEquals(F(10, 1), 1 / F(1, 10))
254 self
.assertTypedEquals(10.0, 1.0 / F(1, 10))
255 self
.assertTypedEquals(10.0 + 0j
, (1.0 + 0j
) / F(1, 10))
257 self
.assertTypedEquals(0, F(1, 10) // 1)
258 self
.assertTypedEquals(0.0, F(1, 10) // 1.0)
259 self
.assertTypedEquals(10, 1 // F(1, 10))
260 self
.assertTypedEquals(10**23, 10**22 // F(1, 10))
261 self
.assertTypedEquals(10.0, 1.0 // F(1, 10))
263 self
.assertTypedEquals(F(1, 10), F(1, 10) % 1)
264 self
.assertTypedEquals(0.1, F(1, 10) % 1.0)
265 self
.assertTypedEquals(F(0, 1), 1 % F(1, 10))
266 self
.assertTypedEquals(0.0, 1.0 % F(1, 10))
268 # No need for divmod since we don't override it.
270 # ** has more interesting conversion rules.
271 self
.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
272 self
.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
273 self
.assertTypedEquals(0.1, F(1, 10) ** 1.0)
274 self
.assertTypedEquals(0.1 + 0j
, F(1, 10) ** (1.0 + 0j
))
275 self
.assertTypedEquals(4 , 2 ** F(2, 1))
276 # Will return 1j in 3.0:
277 self
.assertRaises(ValueError, pow, (-1), F(1, 2))
278 self
.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
279 self
.assertTypedEquals(2.0 , 4 ** F(1, 2))
280 self
.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
281 self
.assertTypedEquals(1.0 + 0j
, (1.0 + 0j
) ** F(1, 10))
283 def testMixingWithDecimal(self
):
284 # Decimal refuses mixed comparisons.
285 self
.assertRaisesMessage(
287 "unsupported operand type(s) for +: 'Fraction' and 'Decimal'",
288 operator
.add
, F(3,11), Decimal('3.1415926'))
289 self
.assertNotEquals(F(5, 2), Decimal('2.5'))
291 def testComparisons(self
):
292 self
.assertTrue(F(1, 2) < F(2, 3))
293 self
.assertFalse(F(1, 2) < F(1, 2))
294 self
.assertTrue(F(1, 2) <= F(2, 3))
295 self
.assertTrue(F(1, 2) <= F(1, 2))
296 self
.assertFalse(F(2, 3) <= F(1, 2))
297 self
.assertTrue(F(1, 2) == F(1, 2))
298 self
.assertFalse(F(1, 2) == F(1, 3))
299 self
.assertFalse(F(1, 2) != F(1, 2))
300 self
.assertTrue(F(1, 2) != F(1, 3))
302 def testMixedLess(self
):
303 self
.assertTrue(2 < F(5, 2))
304 self
.assertFalse(2 < F(4, 2))
305 self
.assertTrue(F(5, 2) < 3)
306 self
.assertFalse(F(4, 2) < 2)
308 self
.assertTrue(F(1, 2) < 0.6)
309 self
.assertFalse(F(1, 2) < 0.4)
310 self
.assertTrue(0.4 < F(1, 2))
311 self
.assertFalse(0.5 < F(1, 2))
313 def testMixedLessEqual(self
):
314 self
.assertTrue(0.5 <= F(1, 2))
315 self
.assertFalse(0.6 <= F(1, 2))
316 self
.assertTrue(F(1, 2) <= 0.5)
317 self
.assertFalse(F(1, 2) <= 0.4)
318 self
.assertTrue(2 <= F(4, 2))
319 self
.assertFalse(2 <= F(3, 2))
320 self
.assertTrue(F(4, 2) <= 2)
321 self
.assertFalse(F(5, 2) <= 2)
323 def testBigFloatComparisons(self
):
324 # Because 10**23 can't be represented exactly as a float:
325 self
.assertFalse(F(10**23) == float(10**23))
326 # The first test demonstrates why these are important.
327 self
.assertFalse(1e23
< float(F(math
.trunc(1e23
) + 1)))
328 self
.assertTrue(1e23
< F(math
.trunc(1e23
) + 1))
329 self
.assertFalse(1e23
<= F(math
.trunc(1e23
) - 1))
330 self
.assertTrue(1e23
> F(math
.trunc(1e23
) - 1))
331 self
.assertFalse(1e23
>= F(math
.trunc(1e23
) + 1))
333 def testBigComplexComparisons(self
):
334 self
.assertFalse(F(10**23) == complex(10**23))
335 self
.assertTrue(F(10**23) > complex(10**23))
336 self
.assertFalse(F(10**23) <= complex(10**23))
338 def testMixedEqual(self
):
339 self
.assertTrue(0.5 == F(1, 2))
340 self
.assertFalse(0.6 == F(1, 2))
341 self
.assertTrue(F(1, 2) == 0.5)
342 self
.assertFalse(F(1, 2) == 0.4)
343 self
.assertTrue(2 == F(4, 2))
344 self
.assertFalse(2 == F(3, 2))
345 self
.assertTrue(F(4, 2) == 2)
346 self
.assertFalse(F(5, 2) == 2)
348 def testStringification(self
):
349 self
.assertEquals("Fraction(7, 3)", repr(F(7, 3)))
350 self
.assertEquals("Fraction(6283185307, 2000000000)",
351 repr(F('3.1415926535')))
352 self
.assertEquals("Fraction(-1, 100000000000000000000)",
354 self
.assertEquals("7/3", str(F(7, 3)))
355 self
.assertEquals("7", str(F(7, 1)))
358 self
.assertEquals(hash(2.5), hash(F(5, 2)))
359 self
.assertEquals(hash(10**50), hash(F(10**50)))
360 self
.assertNotEquals(hash(float(10**23)), hash(F(10**23)))
362 def testApproximatePi(self
):
363 # Algorithm borrowed from
364 # http://docs.python.org/lib/decimal-recipes.html
366 lasts
, t
, s
, n
, na
, d
, da
= 0, three
, 3, 1, 0, 0, 24
367 while abs(s
- lasts
) > F(1, 10**9):
373 self
.assertAlmostEquals(math
.pi
, s
)
375 def testApproximateCos1(self
):
376 # Algorithm borrowed from
377 # http://docs.python.org/lib/decimal-recipes.html
379 i
, lasts
, s
, fact
, num
, sign
= 0, 0, F(1), 1, 1, 1
380 while abs(s
- lasts
) > F(1, 10**9):
386 s
+= num
/ fact
* sign
387 self
.assertAlmostEquals(math
.cos(1), s
)
389 def test_copy_deepcopy_pickle(self
):
391 self
.assertEqual(r
, loads(dumps(r
)))
392 self
.assertEqual(id(r
), id(copy(r
)))
393 self
.assertEqual(id(r
), id(deepcopy(r
)))
396 run_unittest(FractionTest
, GcdTest
)
398 if __name__
== '__main__':