@@ -100,6 +100,49 @@ def check_strtod(self, s):
100
100
"Incorrectly rounded str->float conversion for {}: "
101
101
"expected {}, got {}" .format (s , expected , got ))
102
102
103
+ def test_short_halfway_cases (self ):
104
+ # exact halfway cases with a small number of significant digits
105
+ for k in 0 , 5 , 10 , 15 , 20 :
106
+ # upper = smallest integer >= 2**54/5**k
107
+ upper = - (- 2 ** 54 // 5 ** k )
108
+ # lower = smallest odd number >= 2**53/5**k
109
+ lower = - (- 2 ** 53 // 5 ** k )
110
+ if lower % 2 == 0 :
111
+ lower += 1
112
+ for i in range (10 * TEST_SIZE ):
113
+ # Select a random odd n in [2**53/5**k,
114
+ # 2**54/5**k). Then n * 10**k gives a halfway case
115
+ # with small number of significant digits.
116
+ n , e = random .randrange (lower , upper , 2 ), k
117
+
118
+ # Remove any additional powers of 5.
119
+ while n % 5 == 0 :
120
+ n , e = n // 5 , e + 1
121
+ assert n % 10 in (1 , 3 , 7 , 9 )
122
+
123
+ # Try numbers of the form n * 2**p2 * 10**e, p2 >= 0,
124
+ # until n * 2**p2 has more than 20 significant digits.
125
+ digits , exponent = n , e
126
+ while digits < 10 ** 20 :
127
+ s = '{}e{}' .format (digits , exponent )
128
+ self .check_strtod (s )
129
+ # Same again, but with extra trailing zeros.
130
+ s = '{}e{}' .format (digits * 10 ** 40 , exponent - 40 )
131
+ self .check_strtod (s )
132
+ digits *= 2
133
+
134
+ # Try numbers of the form n * 5**p2 * 10**(e - p5), p5
135
+ # >= 0, with n * 5**p5 < 10**20.
136
+ digits , exponent = n , e
137
+ while digits < 10 ** 20 :
138
+ s = '{}e{}' .format (digits , exponent )
139
+ self .check_strtod (s )
140
+ # Same again, but with extra trailing zeros.
141
+ s = '{}e{}' .format (digits * 10 ** 40 , exponent - 40 )
142
+ self .check_strtod (s )
143
+ digits *= 5
144
+ exponent -= 1
145
+
103
146
def test_halfway_cases (self ):
104
147
# test halfway cases for the round-half-to-even rule
105
148
for i in range (1000 ):
@@ -164,10 +207,10 @@ def test_underflow_boundary(self):
164
207
self .check_strtod (s )
165
208
166
209
def test_bigcomp (self ):
167
- DIG10 = 10 ** 50
168
- for i in range ( 1000 ):
169
- for j in range (TEST_SIZE ):
170
- digits = random .randrange (DIG10 )
210
+ for ndigs in 5 , 10 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 40 , 41 , 50 :
211
+ dig10 = 10 ** ndigs
212
+ for i in range (100 * TEST_SIZE ):
213
+ digits = random .randrange (dig10 )
171
214
exponent = random .randrange (- 400 , 400 )
172
215
s = '{}e{}' .format (digits , exponent )
173
216
self .check_strtod (s )
@@ -254,11 +297,59 @@ def test_particular(self):
254
297
# demonstration that original fix for issue 7632 bug 1 was
255
298
# buggy; the exit condition was too strong
256
299
'247032822920623295e-341' ,
300
+ # demonstrate similar problem to issue 7632 bug1: crash
301
+ # with 'oversized quotient in quorem' message.
302
+ '99037485700245683102805043437346965248029601286431e-373' ,
303
+ '99617639833743863161109961162881027406769510558457e-373' ,
304
+ '98852915025769345295749278351563179840130565591462e-372' ,
305
+ '99059944827693569659153042769690930905148015876788e-373' ,
306
+ '98914979205069368270421829889078356254059760327101e-372' ,
257
307
# issue 7632 bug 5: the following 2 strings convert differently
258
308
'1000000000000000000000000000000000000000e-16' ,
259
309
'10000000000000000000000000000000000000000e-17' ,
310
+ # issue 7632 bug 7
311
+ '991633793189150720000000000000000000000000000000000000000e-33' ,
312
+ # And another, similar, failing halfway case
313
+ '4106250198039490000000000000000000000000000000000000000e-38' ,
260
314
# issue 7632 bug 8: the following produced 10.0
261
315
'10.900000000000000012345678912345678912345' ,
316
+ # exercise exit conditions in bigcomp comparison loop
317
+ '2602129298404963083833853479113577253105939995688e2' ,
318
+ '260212929840496308383385347911357725310593999568896e0' ,
319
+ '26021292984049630838338534791135772531059399956889601e-2' ,
320
+ '260212929840496308383385347911357725310593999568895e0' ,
321
+ '260212929840496308383385347911357725310593999568897e0' ,
322
+ '260212929840496308383385347911357725310593999568996e0' ,
323
+ '260212929840496308383385347911357725310593999568866e0' ,
324
+ # 2**53
325
+ '9007199254740992.00' ,
326
+ # 2**1024 - 2**970: exact overflow boundary. All values
327
+ # smaller than this should round to something finite; any value
328
+ # greater than or equal to this one overflows.
329
+ '179769313486231580793728971405303415079934132710037' #...
330
+ '826936173778980444968292764750946649017977587207096' #...
331
+ '330286416692887910946555547851940402630657488671505' #...
332
+ '820681908902000708383676273854845817711531764475730' #...
333
+ '270069855571366959622842914819860834936475292719074' #...
334
+ '168444365510704342711559699508093042880177904174497792' ,
335
+ # 2**1024 - 2**970 - tiny
336
+ '179769313486231580793728971405303415079934132710037' #...
337
+ '826936173778980444968292764750946649017977587207096' #...
338
+ '330286416692887910946555547851940402630657488671505' #...
339
+ '820681908902000708383676273854845817711531764475730' #...
340
+ '270069855571366959622842914819860834936475292719074' #...
341
+ '168444365510704342711559699508093042880177904174497791.999' ,
342
+ # 2**1024 - 2**970 + tiny
343
+ '179769313486231580793728971405303415079934132710037' #...
344
+ '826936173778980444968292764750946649017977587207096' #...
345
+ '330286416692887910946555547851940402630657488671505' #...
346
+ '820681908902000708383676273854845817711531764475730' #...
347
+ '270069855571366959622842914819860834936475292719074' #...
348
+ '168444365510704342711559699508093042880177904174497792.001' ,
349
+ # 1 - 2**-54, +-tiny
350
+ '999999999999999944488848768742172978818416595458984375e-54' ,
351
+ '9999999999999999444888487687421729788184165954589843749999999e-54' ,
352
+ '9999999999999999444888487687421729788184165954589843750000001e-54' ,
262
353
]
263
354
for s in test_strings :
264
355
self .check_strtod (s )
0 commit comments