mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-120950: Fix overflow in math.log() with large int-like argument (GH-121011)
Handling of arbitrary large int-like argument is now consistent with handling arbitrary large int arguments.
This commit is contained in:
parent
9e7340cd3b
commit
4359706ac8
3 changed files with 111 additions and 30 deletions
|
|
@ -189,6 +189,22 @@ def __init__(self, value):
|
|||
def __index__(self):
|
||||
return self.value
|
||||
|
||||
class IndexableFloatLike:
|
||||
def __init__(self, float_value, index_value):
|
||||
self.float_value = float_value
|
||||
self.index_value = index_value
|
||||
|
||||
def __float__(self):
|
||||
if isinstance(self.float_value, BaseException):
|
||||
raise self.float_value
|
||||
return self.float_value
|
||||
|
||||
def __index__(self):
|
||||
if isinstance(self.index_value, BaseException):
|
||||
raise self.index_value
|
||||
return self.index_value
|
||||
|
||||
|
||||
class BadDescr:
|
||||
def __get__(self, obj, objtype=None):
|
||||
raise ValueError
|
||||
|
|
@ -1192,13 +1208,32 @@ def testLog(self):
|
|||
self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
|
||||
self.ftest('log(10**1000)', math.log(10**1000),
|
||||
2302.5850929940457)
|
||||
self.ftest('log(10**2000, 10**1000)', math.log(10**2000, 10**1000), 2)
|
||||
self.ftest('log(MyIndexable(32), MyIndexable(2))',
|
||||
math.log(MyIndexable(32), MyIndexable(2)), 5)
|
||||
self.ftest('log(MyIndexable(10**1000))',
|
||||
math.log(MyIndexable(10**1000)),
|
||||
2302.5850929940457)
|
||||
self.ftest('log(MyIndexable(10**2000), MyIndexable(10**1000))',
|
||||
math.log(MyIndexable(10**2000), MyIndexable(10**1000)),
|
||||
2)
|
||||
self.assertRaises(ValueError, math.log, 0.0)
|
||||
self.assertRaises(ValueError, math.log, 0)
|
||||
self.assertRaises(ValueError, math.log, MyIndexable(0))
|
||||
self.assertRaises(ValueError, math.log, -1.5)
|
||||
self.assertRaises(ValueError, math.log, -1)
|
||||
self.assertRaises(ValueError, math.log, MyIndexable(-1))
|
||||
self.assertRaises(ValueError, math.log, -10**1000)
|
||||
self.assertRaises(ValueError, math.log, MyIndexable(-10**1000))
|
||||
self.assertRaises(ValueError, math.log, 10, -10)
|
||||
self.assertRaises(ValueError, math.log, NINF)
|
||||
self.assertEqual(math.log(INF), INF)
|
||||
self.assertTrue(math.isnan(math.log(NAN)))
|
||||
|
||||
self.assertEqual(math.log(IndexableFloatLike(math.e, 10**1000)), 1.0)
|
||||
self.assertAlmostEqual(math.log(IndexableFloatLike(OverflowError(), 10**1000)),
|
||||
2302.5850929940457)
|
||||
|
||||
def testLog1p(self):
|
||||
self.assertRaises(TypeError, math.log1p)
|
||||
for n in [2, 2**90, 2**300]:
|
||||
|
|
@ -1214,16 +1249,28 @@ def testLog2(self):
|
|||
self.assertEqual(math.log2(1), 0.0)
|
||||
self.assertEqual(math.log2(2), 1.0)
|
||||
self.assertEqual(math.log2(4), 2.0)
|
||||
self.assertEqual(math.log2(MyIndexable(4)), 2.0)
|
||||
|
||||
# Large integer values
|
||||
self.assertEqual(math.log2(2**1023), 1023.0)
|
||||
self.assertEqual(math.log2(2**1024), 1024.0)
|
||||
self.assertEqual(math.log2(2**2000), 2000.0)
|
||||
self.assertEqual(math.log2(MyIndexable(2**2000)), 2000.0)
|
||||
|
||||
self.assertRaises(ValueError, math.log2, 0.0)
|
||||
self.assertRaises(ValueError, math.log2, 0)
|
||||
self.assertRaises(ValueError, math.log2, MyIndexable(0))
|
||||
self.assertRaises(ValueError, math.log2, -1.5)
|
||||
self.assertRaises(ValueError, math.log2, -1)
|
||||
self.assertRaises(ValueError, math.log2, MyIndexable(-1))
|
||||
self.assertRaises(ValueError, math.log2, -2**2000)
|
||||
self.assertRaises(ValueError, math.log2, MyIndexable(-2**2000))
|
||||
self.assertRaises(ValueError, math.log2, NINF)
|
||||
self.assertTrue(math.isnan(math.log2(NAN)))
|
||||
|
||||
self.assertEqual(math.log2(IndexableFloatLike(8.0, 2**2000)), 3.0)
|
||||
self.assertEqual(math.log2(IndexableFloatLike(OverflowError(), 2**2000)), 2000.0)
|
||||
|
||||
@requires_IEEE_754
|
||||
# log2() is not accurate enough on Mac OS X Tiger (10.4)
|
||||
@support.requires_mac_ver(10, 5)
|
||||
|
|
@ -1239,12 +1286,24 @@ def testLog10(self):
|
|||
self.ftest('log10(1)', math.log10(1), 0)
|
||||
self.ftest('log10(10)', math.log10(10), 1)
|
||||
self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
|
||||
self.ftest('log10(MyIndexable(10))', math.log10(MyIndexable(10)), 1)
|
||||
self.ftest('log10(MyIndexable(10**1000))',
|
||||
math.log10(MyIndexable(10**1000)), 1000.0)
|
||||
self.assertRaises(ValueError, math.log10, 0.0)
|
||||
self.assertRaises(ValueError, math.log10, 0)
|
||||
self.assertRaises(ValueError, math.log10, MyIndexable(0))
|
||||
self.assertRaises(ValueError, math.log10, -1.5)
|
||||
self.assertRaises(ValueError, math.log10, -1)
|
||||
self.assertRaises(ValueError, math.log10, MyIndexable(-1))
|
||||
self.assertRaises(ValueError, math.log10, -10**1000)
|
||||
self.assertRaises(ValueError, math.log10, MyIndexable(-10**1000))
|
||||
self.assertRaises(ValueError, math.log10, NINF)
|
||||
self.assertEqual(math.log(INF), INF)
|
||||
self.assertTrue(math.isnan(math.log10(NAN)))
|
||||
|
||||
self.assertEqual(math.log10(IndexableFloatLike(100.0, 10**1000)), 2.0)
|
||||
self.assertEqual(math.log10(IndexableFloatLike(OverflowError(), 10**1000)), 1000.0)
|
||||
|
||||
@support.bigmemtest(2**32, memuse=0.2)
|
||||
def test_log_huge_integer(self, size):
|
||||
v = 1 << size
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue