blob: ed5109fb12504ea9528d9565540272a540a42652 [file] [log] [blame]
Michael W. Hudsonba283e22005-05-27 15:23:20 +00001
2import unittest, struct
Christian Heimes284d9272007-12-10 22:28:56 +00003import os
Michael W. Hudsonba283e22005-05-27 15:23:20 +00004from test import test_support
5
6class FormatFunctionsTestCase(unittest.TestCase):
7
8 def setUp(self):
9 self.save_formats = {'double':float.__getformat__('double'),
10 'float':float.__getformat__('float')}
11
12 def tearDown(self):
13 float.__setformat__('double', self.save_formats['double'])
14 float.__setformat__('float', self.save_formats['float'])
15
16 def test_getformat(self):
17 self.assert_(float.__getformat__('double') in
18 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
19 self.assert_(float.__getformat__('float') in
20 ['unknown', 'IEEE, big-endian', 'IEEE, little-endian'])
21 self.assertRaises(ValueError, float.__getformat__, 'chicken')
22 self.assertRaises(TypeError, float.__getformat__, 1)
23
24 def test_setformat(self):
25 for t in 'double', 'float':
26 float.__setformat__(t, 'unknown')
27 if self.save_formats[t] == 'IEEE, big-endian':
28 self.assertRaises(ValueError, float.__setformat__,
29 t, 'IEEE, little-endian')
30 elif self.save_formats[t] == 'IEEE, little-endian':
31 self.assertRaises(ValueError, float.__setformat__,
32 t, 'IEEE, big-endian')
33 else:
34 self.assertRaises(ValueError, float.__setformat__,
35 t, 'IEEE, big-endian')
36 self.assertRaises(ValueError, float.__setformat__,
37 t, 'IEEE, little-endian')
38 self.assertRaises(ValueError, float.__setformat__,
39 t, 'chicken')
40 self.assertRaises(ValueError, float.__setformat__,
41 'chicken', 'unknown')
42
43BE_DOUBLE_INF = '\x7f\xf0\x00\x00\x00\x00\x00\x00'
44LE_DOUBLE_INF = ''.join(reversed(BE_DOUBLE_INF))
45BE_DOUBLE_NAN = '\x7f\xf8\x00\x00\x00\x00\x00\x00'
46LE_DOUBLE_NAN = ''.join(reversed(BE_DOUBLE_NAN))
47
48BE_FLOAT_INF = '\x7f\x80\x00\x00'
49LE_FLOAT_INF = ''.join(reversed(BE_FLOAT_INF))
50BE_FLOAT_NAN = '\x7f\xc0\x00\x00'
51LE_FLOAT_NAN = ''.join(reversed(BE_FLOAT_NAN))
52
53# on non-IEEE platforms, attempting to unpack a bit pattern
54# representing an infinity or a NaN should raise an exception.
55
56class UnknownFormatTestCase(unittest.TestCase):
57 def setUp(self):
58 self.save_formats = {'double':float.__getformat__('double'),
59 'float':float.__getformat__('float')}
60 float.__setformat__('double', 'unknown')
61 float.__setformat__('float', 'unknown')
Tim Peters5d36a552005-06-03 22:40:27 +000062
Michael W. Hudsonba283e22005-05-27 15:23:20 +000063 def tearDown(self):
64 float.__setformat__('double', self.save_formats['double'])
65 float.__setformat__('float', self.save_formats['float'])
66
67 def test_double_specials_dont_unpack(self):
68 for fmt, data in [('>d', BE_DOUBLE_INF),
69 ('>d', BE_DOUBLE_NAN),
70 ('<d', LE_DOUBLE_INF),
71 ('<d', LE_DOUBLE_NAN)]:
72 self.assertRaises(ValueError, struct.unpack, fmt, data)
73
74 def test_float_specials_dont_unpack(self):
75 for fmt, data in [('>f', BE_FLOAT_INF),
76 ('>f', BE_FLOAT_NAN),
77 ('<f', LE_FLOAT_INF),
78 ('<f', LE_FLOAT_NAN)]:
79 self.assertRaises(ValueError, struct.unpack, fmt, data)
80
81
82# on an IEEE platform, all we guarantee is that bit patterns
83# representing infinities or NaNs do not raise an exception; all else
84# is accident (today).
Alex Martellid8672aa2007-08-22 21:14:17 +000085# let's also try to guarantee that -0.0 and 0.0 don't get confused.
Michael W. Hudsonba283e22005-05-27 15:23:20 +000086
87class IEEEFormatTestCase(unittest.TestCase):
88 if float.__getformat__("double").startswith("IEEE"):
89 def test_double_specials_do_unpack(self):
90 for fmt, data in [('>d', BE_DOUBLE_INF),
91 ('>d', BE_DOUBLE_NAN),
92 ('<d', LE_DOUBLE_INF),
93 ('<d', LE_DOUBLE_NAN)]:
94 struct.unpack(fmt, data)
95
96 if float.__getformat__("float").startswith("IEEE"):
97 def test_float_specials_do_unpack(self):
98 for fmt, data in [('>f', BE_FLOAT_INF),
99 ('>f', BE_FLOAT_NAN),
100 ('<f', LE_FLOAT_INF),
101 ('<f', LE_FLOAT_NAN)]:
102 struct.unpack(fmt, data)
103
Alex Martellid8672aa2007-08-22 21:14:17 +0000104 if float.__getformat__("double").startswith("IEEE"):
105 def test_negative_zero(self):
106 import math
107 def pos_pos():
108 return 0.0, math.atan2(0.0, -1)
109 def pos_neg():
110 return 0.0, math.atan2(-0.0, -1)
111 def neg_pos():
112 return -0.0, math.atan2(0.0, -1)
113 def neg_neg():
114 return -0.0, math.atan2(-0.0, -1)
115 self.assertEquals(pos_pos(), neg_pos())
116 self.assertEquals(pos_neg(), neg_neg())
117
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000118
Christian Heimes284d9272007-12-10 22:28:56 +0000119class ReprTestCase(unittest.TestCase):
120 def test_repr(self):
121 floats_file = open(os.path.join(os.path.split(__file__)[0],
122 'floating_points.txt'))
123 for line in floats_file:
124 line = line.strip()
125 if not line or line.startswith('#'):
126 continue
127 v = eval(line)
128 self.assertEqual(v, eval(repr(v)))
129 floats_file.close()
130
131
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000132def test_main():
133 test_support.run_unittest(
134 FormatFunctionsTestCase,
135 UnknownFormatTestCase,
Christian Heimes284d9272007-12-10 22:28:56 +0000136 IEEEFormatTestCase,
Christian Heimesf15c66e2007-12-11 00:54:34 +0000137 #ReprTestCase
138 )
Michael W. Hudsonba283e22005-05-27 15:23:20 +0000139
140if __name__ == '__main__':
141 test_main()