8
+ from numpy .testing import assert_ , assert_equal , run_module_suite
9
9
10
10
11
11
class TestRealScalars (object ):
@@ -26,6 +26,172 @@ def test_str(self):
26
26
msg = 'for str({}({}))' .format (np .dtype (styp ).name , repr (val ))
27
27
assert_equal (str (styp (val )), want , err_msg = msg )
28
28
29
+ def test_dragon4 (self ):
30
+ # these tests are adapted from Ryan Juckett's dragon4 implementation,
31
+ # see dragon4.c for details.
32
+
33
+ fpos32 = lambda x , ** k : np .format_float_positional (np .float32 (x ), ** k )
34
+ fsci32 = lambda x , ** k : np .format_float_scientific (np .float32 (x ), ** k )
35
+ fpos64 = lambda x , ** k : np .format_float_positional (np .float64 (x ), ** k )
36
+ fsci64 = lambda x , ** k : np .format_float_scientific (np .float64 (x ), ** k )
37
+
38
+ preckwd = lambda prec : {'unique' : False , 'precision' : prec }
39
+
40
+ assert_equal (fpos32 ('1.0' ), "1." )
41
+ assert_equal (fsci32 ('1.0' ), "1.e+00" )
42
+ assert_equal (fpos32 ('10.234' ), "10.234" )
43
+ assert_equal (fpos32 ('-10.234' ), "-10.234" )
44
+ assert_equal (fsci32 ('10.234' ), "1.0234e+01" )
45
+ assert_equal(fsci32 ('-10.234' ), "-1.0234e+01" )
46
+ assert_equal (fpos32 ('1000.0' ), "1000." )
47
+ assert_equal (fpos32 ('1.0' , precision = 0 ), "1." )
48
+ assert_equal (fsci32 ('1.0' , precision = 0 ), "1.e+00" )
49
+ assert_equal (fpos32 ('10.234' , precision = 0 ), "10." )
50
+ assert_equal (fpos32 ('-10.234' , precision = 0 ), "-10." )
51
+ assert_equal (fsci32 ('10.234' , precision = 0 ), "1.e+01" )
52
+ assert_equal (fsci32 ('-10.234' , precision = 0 ), "-1.e+01" )
53
+ assert_equal (fpos32 ('10.234' , precision = 2 ), "10.23" )
54
+ assert_equal (fsci32 ('-10.234' , precision = 2 ), "-1.02e+01" )
55
+ assert_equal (fsci64 ('9.9999999999999995e-08' , ** preckwd (16 )),
56
+ '9.9999999999999995e-08' )
57
+ assert_equal (fsci64 ('9.8813129168249309e-324' , ** preckwd (16 )),
58
+ '9.8813129168249309e-324' )
59
+ assert_equal (fsci64 ('9.9999999999999694e-311' , ** preckwd (16 )),
60
+ '9.9999999999999694e-311' )
61
+
62
+
63
+ # test rounding
64
+ # 3.1415927410 is closest float32 to np.pi
65
+ assert_equal (fpos32 ('3.14159265358979323846' , ** preckwd (10 )),
66
+ "3.1415927410" )
67
+ assert_equal (fsci32 ('3.14159265358979323846' , ** preckwd (10 )),
68
+ "3.1415927410e+00" )
69
+ assert_equal (fpos64 ('3.14159265358979323846' , ** preckwd (10 )),
70
+ "3.1415926536" )
71
+ assert_equal (fsci64 ('3.14159265358979323846' , ** preckwd (10 )),
72
+ "3.1415926536e+00" )
73
+ # 299792448 is closest float32 to 299792458
74
+ assert_equal (fpos32 ('299792458.0' , ** preckwd (5 )), "299792448.00000" )
75
+ assert_equal (fsci32 ('299792458.0' , ** preckwd (5 )), "2.99792e+08" )
76
+ assert_equal (fpos64 ('299792458.0' , ** preckwd (5 )), "299792458.00000" )
77
+ assert_equal (fsci64 ('299792458.0' , ** preckwd (5 )), "2.99792e+08" )
78
+
79
+ assert_equal (fpos32 ('3.14159265358979323846' , ** preckwd (25 )),
80
+ "3.1415927410125732421875000" )
81
+ assert_equal (fpos64 ('3.14159265358979323846' , ** preckwd (50 )),
82
+ "3.14159265358979311599796346854418516159057617187500" )
83
+ assert_equal (fpos64 ('3.14159265358979323846' ), "3.141592653589793" )
84
+
85
+
86
+ # smallest numbers
87
+ assert_equal (fpos32 (0.5 ** (126 + 23 ), unique = False , precision = 149 ),
88
+ "0.00000000000000000000000000000000000000000000140129846432"
89
+ "4817070923729583289916131280261941876515771757068283889791"
90
+ "08268586060148663818836212158203125" )
91
+ assert_equal (fpos64 (0.5 ** (1022 + 52 ), unique = False , precision = 1074 ),
92
+ "0.00000000000000000000000000000000000000000000000000000000"
93
+ "0000000000000000000000000000000000000000000000000000000000"
94
+ "0000000000000000000000000000000000000000000000000000000000"
95
+ "0000000000000000000000000000000000000000000000000000000000"
96
+ "0000000000000000000000000000000000000000000000000000000000"
97
+ "0000000000000000000000000000000000049406564584124654417656"
98
+ "8792868221372365059802614324764425585682500675507270208751"
99
+ "8652998363616359923797965646954457177309266567103559397963"
100
+ "9877479601078187812630071319031140452784581716784898210368"
101
+ "8718636056998730723050006387409153564984387312473397273169"
102
+ "6151400317153853980741262385655911710266585566867681870395"
103
+ "6031062493194527159149245532930545654440112748012970999954"
104
+ "1931989409080416563324524757147869014726780159355238611550"
105
+ "1348035264934720193790268107107491703332226844753335720832"
106
+ "4319360923828934583680601060115061698097530783422773183292"
107
+ "4790498252473077637592724787465608477820373446969953364701"
108
+ "7972677717585125660551199131504891101451037862738167250955"
109
+ "8373897335989936648099411642057026370902792427675445652290"
110
+ "87538682506419718265533447265625" )
111
+
112
+ # largest numbers
113
+ assert_equal (fpos32 (np .finfo (np .float32 ).max , ** preckwd (0 )),
114
+ "340282346638528859811704183484516925440." )
115
+ assert_equal (fpos64 (np .finfo (np .float64 ).max , ** preckwd (0 )),
116
+ "1797693134862315708145274237317043567980705675258449965989"
117
+ "1747680315726078002853876058955863276687817154045895351438"
118
+ "2464234321326889464182768467546703537516986049910576551282"
119
+ "0762454900903893289440758685084551339423045832369032229481"
120
+ "6580855933212334827479782620414472316873817718091929988125"
121
+ "0404026184124858368." )
122
+ # Warning: In unique mode only the integer digits necessary for
123
+ # uniqueness are computed, the rest are 0. Should we change this?
124
+ assert_equal (fpos32 (np .finfo (np .float32 ).max , precision = 0 ),
125
+ "340282350000000000000000000000000000000." )
126
+
127
+ # test trailing zeros
128
+ assert_equal (fpos32 ('1.0' , unique = False , precision = 3 ), "1.000" )
129
+ assert_equal (fpos64 ('1.0' , unique = False , precision = 3 ), "1.000" )
130
+ assert_equal (fsci32 ('1.0' , unique = False , precision = 3 ), "1.000e+00" )
131
+ assert_equal (fsci64 ('1.0' , unique = False , precision = 3 ), "1.000e+00" )
132
+ assert_equal (fpos32 ('1.5' , unique = False , precision = 3 ), "1.500" )
133
+ assert_equal (fpos64 ('1.5' , unique = False , precision = 3 ), "1.500" )
134
+ assert_equal (fsci32 ('1.5' , unique = False , precision = 3 ), "1.500e+00" )
135
+ assert_equal (fsci64 ('1.5' , unique = False , precision = 3 ), "1.500e+00" )
136
+
137
+ def test_dragon4_interface (self ):
138
+ tps = [np .float16 , np .float32 , np .float64 ]
139
+ if hasattr (np , 'float128' ):
140
+ tps .append (np .float128 )
141
+
142
+ fpos = np .format_float_positional
143
+ fsci = np .format_float_scientific
144
+
145
+ for tp in tps :
146
+ # test padding
147
+ assert_equal (fpos (tp ('1.0' ), pad_left = 4 , pad_right = 4 ), " 1. " )
148
+ assert_equal (fpos (tp ('-1.0' ), pad_left = 4 , pad_right = 4 ), " -1. " )
149
+ assert_equal (fpos (tp ('-10.2' ),
150
+ pad_left = 4 , pad_right = 4 ), " -10.2 " )
151
+
152
+ # test exp_digits
153
+ assert_equal (fsci (tp ('1.23e1' ), exp_digits = 5 ), "1.23e+00001" )
154
+
155
+ # test fixed (non-unique) mode
156
+ assert_equal (fpos (tp ('1.0' ), unique = False , precision = 4 ), "1.0000" )
157
+ assert_equal (fsci (tp ('1.0' ), unique = False , precision = 4 ),
158
+ "1.0000e+00" )
159
+
160
+ # test trimming
161
+ # trim of 'k' or '.' only affects non-unique mode, since unique
162
+ # mode will not output trailing 0s.
163
+ assert_equal (fpos (tp ('1.' ), unique = False , precision = 4 , trim = 'k' ),
164
+ "1.0000" )
165
+
166
+ assert_equal (fpos (tp ('1.' ), unique = False , precision = 4 , trim = '.' ),
167
+ "1." )
168
+ assert_equal (fpos (tp ('1.2' ), unique = False , precision = 4 , trim = '.' ),
169
+ "1.2" if tp != np .float16 else "1.2002" )
170
+
171
+ assert_equal (fpos (tp ('1.' ), unique = False , precision = 4 , trim = '0' ),
172
+
C963
"1.0" )
173
+ assert_equal (fpos (tp ('1.2' ), unique = False , precision = 4 , trim = '0' ),
174
+ "1.2" if tp != np .float16 else "1.2002" )
175
+ assert_equal (fpos (tp ('1.' ), trim = '0' ), "1.0" )
176
+
177
+ assert_equal (fpos (tp ('1.' ), unique = False , precision = 4 , trim = '-' ),
178
+ "1" )
179
+ assert_equal (fpos (tp ('1.2' ), unique = False , precision = 4 , trim = '-' ),
180
+ "1.2" if tp != np .float16 else "1.2002" )
181
+ assert_equal (fpos (tp ('1.' ), trim = '-' ), "1" )
182
+
183
+ def float32_roundtrip (self ):
184
+ # gh-9360
185
+ x = np .float32 (1024 - 2 ** - 14 )
186
+ y = np .float32 (1024 - 2 ** - 13 )
187
+ assert_ (repr (x ) != repr (y ))
188
+ assert_equal (np .float32 (repr (x )), x )
189
+ assert_equal (np .float32 (repr (y )), y )
190
+
191
+ def float64_vs_python (self ):
192
+ # gh-2643, gh-6136, gh-6908
193
+ assert_equal (repr (np .float64 (0.1 )), repr (0.1 ))
194
+ assert_ (repr (np .float64 (0.20000000000000004 )) != repr (0.2 ))
29
195
30
196
if __name__ == "__main__" :
31
197
run_module_suite ()
0 commit comments