File Lib/test/test_long.py changed (mode: 100644) (index fd15f04ace..cc48259e35) |
... |
... |
class LongTest(unittest.TestCase): |
906 |
906 |
self.check_truediv(-x, y) |
self.check_truediv(-x, y) |
907 |
907 |
self.check_truediv(-x, -y) |
self.check_truediv(-x, -y) |
908 |
908 |
|
|
|
909 |
|
def test_negative_shift_count(self): |
|
910 |
|
with self.assertRaises(ValueError): |
|
911 |
|
42 << -3 |
|
912 |
|
with self.assertRaises(ValueError): |
|
913 |
|
42 << -(1 << 1000) |
|
914 |
|
with self.assertRaises(ValueError): |
|
915 |
|
42 >> -3 |
|
916 |
|
with self.assertRaises(ValueError): |
|
917 |
|
42 >> -(1 << 1000) |
|
918 |
|
|
909 |
919 |
def test_lshift_of_zero(self): |
def test_lshift_of_zero(self): |
910 |
920 |
self.assertEqual(0 << 0, 0) |
self.assertEqual(0 << 0, 0) |
911 |
921 |
self.assertEqual(0 << 10, 0) |
self.assertEqual(0 << 10, 0) |
912 |
922 |
with self.assertRaises(ValueError): |
with self.assertRaises(ValueError): |
913 |
923 |
0 << -1 |
0 << -1 |
|
924 |
|
self.assertEqual(0 << (1 << 1000), 0) |
|
925 |
|
with self.assertRaises(ValueError): |
|
926 |
|
0 << -(1 << 1000) |
914 |
927 |
|
|
915 |
928 |
@support.cpython_only |
@support.cpython_only |
916 |
929 |
def test_huge_lshift_of_zero(self): |
def test_huge_lshift_of_zero(self): |
|
... |
... |
class LongTest(unittest.TestCase): |
918 |
931 |
# Other implementations may have a different boundary for overflow, |
# Other implementations may have a different boundary for overflow, |
919 |
932 |
# or not raise at all. |
# or not raise at all. |
920 |
933 |
self.assertEqual(0 << sys.maxsize, 0) |
self.assertEqual(0 << sys.maxsize, 0) |
921 |
|
with self.assertRaises(OverflowError): |
|
922 |
|
0 << (sys.maxsize + 1) |
|
|
934 |
|
self.assertEqual(0 << (sys.maxsize + 1), 0) |
|
935 |
|
|
|
936 |
|
@support.cpython_only |
|
937 |
|
@support.bigmemtest(sys.maxsize + 1000, memuse=2/15 * 2, dry_run=False) |
|
938 |
|
def test_huge_lshift(self, size): |
|
939 |
|
self.assertEqual(1 << (sys.maxsize + 1000), 1 << 1000 << sys.maxsize) |
|
940 |
|
|
|
941 |
|
def test_huge_rshift(self): |
|
942 |
|
self.assertEqual(42 >> (1 << 1000), 0) |
|
943 |
|
self.assertEqual((-42) >> (1 << 1000), -1) |
|
944 |
|
|
|
945 |
|
@support.cpython_only |
|
946 |
|
@support.bigmemtest(sys.maxsize + 500, memuse=2/15, dry_run=False) |
|
947 |
|
def test_huge_rshift_of_huge(self, size): |
|
948 |
|
huge = ((1 << 500) + 11) << sys.maxsize |
|
949 |
|
self.assertEqual(huge >> (sys.maxsize + 1), (1 << 499) + 5) |
|
950 |
|
self.assertEqual(huge >> (sys.maxsize + 1000), 0) |
923 |
951 |
|
|
924 |
952 |
def test_small_ints(self): |
def test_small_ints(self): |
925 |
953 |
for i in range(-5, 257): |
for i in range(-5, 257): |
File Objects/longobject.c changed (mode: 100644) (index 459eed9ab0..4862b76da6) |
... |
... |
long_bool(PyLongObject *v) |
4277 |
4277 |
return Py_SIZE(v) != 0; |
return Py_SIZE(v) != 0; |
4278 |
4278 |
} |
} |
4279 |
4279 |
|
|
|
4280 |
|
/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ |
|
4281 |
|
static int |
|
4282 |
|
divmod_shift(PyLongObject *shiftby, Py_ssize_t *wordshift, digit *remshift) |
|
4283 |
|
{ |
|
4284 |
|
assert(PyLong_Check((PyObject *)shiftby)); |
|
4285 |
|
assert(Py_SIZE(shiftby) >= 0); |
|
4286 |
|
Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby); |
|
4287 |
|
if (lshiftby >= 0) { |
|
4288 |
|
*wordshift = lshiftby / PyLong_SHIFT; |
|
4289 |
|
*remshift = lshiftby % PyLong_SHIFT; |
|
4290 |
|
return 0; |
|
4291 |
|
} |
|
4292 |
|
/* PyLong_Check(shiftby) is true and Py_SIZE(shiftby) >= 0, so it must |
|
4293 |
|
be that PyLong_AsSsize_t raised an OverflowError. */ |
|
4294 |
|
assert(PyErr_ExceptionMatches(PyExc_OverflowError)); |
|
4295 |
|
PyErr_Clear(); |
|
4296 |
|
PyLongObject *wordshift_obj = divrem1(shiftby, PyLong_SHIFT, remshift); |
|
4297 |
|
if (wordshift_obj == NULL) { |
|
4298 |
|
return -1; |
|
4299 |
|
} |
|
4300 |
|
*wordshift = PyLong_AsSsize_t((PyObject *)wordshift_obj); |
|
4301 |
|
Py_DECREF(wordshift_obj); |
|
4302 |
|
if (*wordshift >= 0 && *wordshift < PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(digit)) { |
|
4303 |
|
return 0; |
|
4304 |
|
} |
|
4305 |
|
PyErr_Clear(); |
|
4306 |
|
/* Clip the value. With such large wordshift the right shift |
|
4307 |
|
returns 0 and the left shift raises an error in _PyLong_New(). */ |
|
4308 |
|
*wordshift = PY_SSIZE_T_MAX / sizeof(digit); |
|
4309 |
|
*remshift = 0; |
|
4310 |
|
return 0; |
|
4311 |
|
} |
|
4312 |
|
|
4280 |
4313 |
static PyObject * |
static PyObject * |
4281 |
4314 |
long_rshift(PyLongObject *a, PyLongObject *b) |
long_rshift(PyLongObject *a, PyLongObject *b) |
4282 |
4315 |
{ |
{ |
4283 |
4316 |
PyLongObject *z = NULL; |
PyLongObject *z = NULL; |
4284 |
|
Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j; |
|
4285 |
|
digit lomask, himask; |
|
|
4317 |
|
Py_ssize_t newsize, wordshift, hishift, i, j; |
|
4318 |
|
digit loshift, lomask, himask; |
4286 |
4319 |
|
|
4287 |
4320 |
CHECK_BINOP(a, b); |
CHECK_BINOP(a, b); |
4288 |
4321 |
|
|
|
4322 |
|
if (Py_SIZE(b) < 0) { |
|
4323 |
|
PyErr_SetString(PyExc_ValueError, |
|
4324 |
|
"negative shift count"); |
|
4325 |
|
return NULL; |
|
4326 |
|
} |
|
4327 |
|
|
4289 |
4328 |
if (Py_SIZE(a) < 0) { |
if (Py_SIZE(a) < 0) { |
4290 |
4329 |
/* Right shifting negative numbers is harder */ |
/* Right shifting negative numbers is harder */ |
4291 |
4330 |
PyLongObject *a1, *a2; |
PyLongObject *a1, *a2; |
|
... |
... |
long_rshift(PyLongObject *a, PyLongObject *b) |
4300 |
4339 |
Py_DECREF(a2); |
Py_DECREF(a2); |
4301 |
4340 |
} |
} |
4302 |
4341 |
else { |
else { |
4303 |
|
shiftby = PyLong_AsSsize_t((PyObject *)b); |
|
4304 |
|
if (shiftby == -1L && PyErr_Occurred()) |
|
4305 |
|
return NULL; |
|
4306 |
|
if (shiftby < 0) { |
|
4307 |
|
PyErr_SetString(PyExc_ValueError, |
|
4308 |
|
"negative shift count"); |
|
|
4342 |
|
if (divmod_shift(b, &wordshift, &loshift) < 0) |
4309 |
4343 |
return NULL; |
return NULL; |
4310 |
|
} |
|
4311 |
|
wordshift = shiftby / PyLong_SHIFT; |
|
4312 |
|
newsize = Py_ABS(Py_SIZE(a)) - wordshift; |
|
|
4344 |
|
newsize = Py_SIZE(a) - wordshift; |
4313 |
4345 |
if (newsize <= 0) |
if (newsize <= 0) |
4314 |
4346 |
return PyLong_FromLong(0); |
return PyLong_FromLong(0); |
4315 |
|
loshift = shiftby % PyLong_SHIFT; |
|
4316 |
4347 |
hishift = PyLong_SHIFT - loshift; |
hishift = PyLong_SHIFT - loshift; |
4317 |
4348 |
lomask = ((digit)1 << hishift) - 1; |
lomask = ((digit)1 << hishift) - 1; |
4318 |
4349 |
himask = PyLong_MASK ^ lomask; |
himask = PyLong_MASK ^ lomask; |
|
... |
... |
long_lshift(PyObject *v, PyObject *w) |
4336 |
4367 |
PyLongObject *a = (PyLongObject*)v; |
PyLongObject *a = (PyLongObject*)v; |
4337 |
4368 |
PyLongObject *b = (PyLongObject*)w; |
PyLongObject *b = (PyLongObject*)w; |
4338 |
4369 |
PyLongObject *z = NULL; |
PyLongObject *z = NULL; |
4339 |
|
Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j; |
|
|
4370 |
|
Py_ssize_t oldsize, newsize, wordshift, i, j; |
|
4371 |
|
digit remshift; |
4340 |
4372 |
twodigits accum; |
twodigits accum; |
4341 |
4373 |
|
|
4342 |
4374 |
CHECK_BINOP(a, b); |
CHECK_BINOP(a, b); |
4343 |
4375 |
|
|
4344 |
|
shiftby = PyLong_AsSsize_t((PyObject *)b); |
|
4345 |
|
if (shiftby == -1L && PyErr_Occurred()) |
|
4346 |
|
return NULL; |
|
4347 |
|
if (shiftby < 0) { |
|
|
4376 |
|
if (Py_SIZE(b) < 0) { |
4348 |
4377 |
PyErr_SetString(PyExc_ValueError, "negative shift count"); |
PyErr_SetString(PyExc_ValueError, "negative shift count"); |
4349 |
4378 |
return NULL; |
return NULL; |
4350 |
4379 |
} |
} |
4351 |
|
|
|
4352 |
4380 |
if (Py_SIZE(a) == 0) { |
if (Py_SIZE(a) == 0) { |
4353 |
4381 |
return PyLong_FromLong(0); |
return PyLong_FromLong(0); |
4354 |
4382 |
} |
} |
4355 |
4383 |
|
|
4356 |
|
/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ |
|
4357 |
|
wordshift = shiftby / PyLong_SHIFT; |
|
4358 |
|
remshift = shiftby - wordshift * PyLong_SHIFT; |
|
4359 |
|
|
|
|
4384 |
|
if (divmod_shift(b, &wordshift, &remshift) < 0) |
|
4385 |
|
return NULL; |
4360 |
4386 |
oldsize = Py_ABS(Py_SIZE(a)); |
oldsize = Py_ABS(Py_SIZE(a)); |
4361 |
4387 |
newsize = oldsize + wordshift; |
newsize = oldsize + wordshift; |
4362 |
4388 |
if (remshift) |
if (remshift) |