Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
a0021598
Commit
a0021598
authored
Jun 13, 2005
by
Walter Dörwald
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Port test_long.py to unittest.
parent
f2ca5af4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
451 additions
and
508 deletions
+451
-508
Lib/test/test_long.py
Lib/test/test_long.py
+451
-508
No files found.
Lib/test/test_long.py
View file @
a0021598
from
test.test_support
import
verify
,
verbose
,
TestFailed
,
fcmp
import
unittest
from
string
import
join
from
test
import
test_support
from
random
import
random
,
randint
import
random
# Used for lazy formatting of failure messages
class
Frm
(
object
):
def
__init__
(
self
,
format
,
*
args
):
self
.
format
=
format
self
.
args
=
args
def
__str__
(
self
):
return
self
.
format
%
self
.
args
# SHIFT should match the value in longintrepr.h for best testing.
# SHIFT should match the value in longintrepr.h for best testing.
SHIFT
=
15
SHIFT
=
15
...
@@ -26,518 +36,451 @@ del p2
...
@@ -26,518 +36,451 @@ del p2
special
=
special
+
map
(
lambda
x
:
~
x
,
special
)
+
\
special
=
special
+
map
(
lambda
x
:
~
x
,
special
)
+
\
map
(
lambda
x
:
-
x
,
special
)
map
(
lambda
x
:
-
x
,
special
)
# ------------------------------------------------------------ utilities
# Use check instead of assert so the test still does something
# under -O.
def
check
(
ok
,
*
args
):
if
not
ok
:
raise
TestFailed
,
join
(
map
(
str
,
args
),
" "
)
# Get quasi-random long consisting of ndigits digits (in base BASE).
# quasi == the most-significant digit will not be 0, and the number
# is constructed to contain long strings of 0 and 1 bits. These are
# more likely than random bits to provoke digit-boundary errors.
# The sign of the number is also random.
def
getran
(
ndigits
):
verify
(
ndigits
>
0
)
nbits_hi
=
ndigits
*
SHIFT
nbits_lo
=
nbits_hi
-
SHIFT
+
1
answer
=
0L
nbits
=
0
r
=
int
(
random
()
*
(
SHIFT
*
2
))
|
1
# force 1 bits to start
while
nbits
<
nbits_lo
:
bits
=
(
r
>>
1
)
+
1
bits
=
min
(
bits
,
nbits_hi
-
nbits
)
verify
(
1
<=
bits
<=
SHIFT
)
nbits
=
nbits
+
bits
answer
=
answer
<<
bits
if
r
&
1
:
answer
=
answer
|
((
1
<<
bits
)
-
1
)
r
=
int
(
random
()
*
(
SHIFT
*
2
))
verify
(
nbits_lo
<=
nbits
<=
nbits_hi
)
if
random
()
<
0.5
:
answer
=
-
answer
return
answer
# Get random long consisting of ndigits random digits (relative to base
# BASE). The sign bit is also random.
def
getran2
(
ndigits
):
answer
=
0L
for
i
in
range
(
ndigits
):
answer
=
(
answer
<<
SHIFT
)
|
randint
(
0
,
MASK
)
if
random
()
<
0.5
:
answer
=
-
answer
return
answer
# --------------------------------------------------------------- divmod
def
test_division_2
(
x
,
y
):
q
,
r
=
divmod
(
x
,
y
)
q2
,
r2
=
x
//
y
,
x
%
y
pab
,
pba
=
x
*
y
,
y
*
x
check
(
pab
==
pba
,
"multiplication does not commute for"
,
x
,
y
)
check
(
q
==
q2
,
"divmod returns different quotient than / for"
,
x
,
y
)
check
(
r
==
r2
,
"divmod returns different mod than % for"
,
x
,
y
)
check
(
x
==
q
*
y
+
r
,
"x != q*y + r after divmod on"
,
x
,
y
)
if
y
>
0
:
check
(
0
<=
r
<
y
,
"bad mod from divmod on"
,
x
,
y
)
else
:
check
(
y
<
r
<=
0
,
"bad mod from divmod on"
,
x
,
y
)
def
test_division
(
maxdigits
=
MAXDIGITS
):
if
verbose
:
print
"long / * % divmod"
digits
=
range
(
1
,
maxdigits
+
1
)
+
range
(
KARATSUBA_CUTOFF
,
KARATSUBA_CUTOFF
+
14
)
digits
.
append
(
KARATSUBA_CUTOFF
*
3
)
for
lenx
in
digits
:
x
=
getran
(
lenx
)
for
leny
in
digits
:
y
=
getran
(
leny
)
or
1L
test_division_2
(
x
,
y
)
# ------------------------------------------------------------ karatsuba
def
test_karatsuba
():
if
verbose
:
print
"Karatsuba"
digits
=
range
(
1
,
5
)
+
range
(
KARATSUBA_CUTOFF
,
KARATSUBA_CUTOFF
+
10
)
digits
.
extend
([
KARATSUBA_CUTOFF
*
10
,
KARATSUBA_CUTOFF
*
100
])
bits
=
[
digit
*
SHIFT
for
digit
in
digits
]
# Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
# 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
for
abits
in
bits
:
a
=
(
1L
<<
abits
)
-
1
for
bbits
in
bits
:
if
bbits
<
abits
:
continue
b
=
(
1L
<<
bbits
)
-
1
x
=
a
*
b
y
=
((
1L
<<
(
abits
+
bbits
))
-
(
1L
<<
abits
)
-
(
1L
<<
bbits
)
+
1
)
check
(
x
==
y
,
"bad result for"
,
a
,
"*"
,
b
,
x
,
y
)
# -------------------------------------------------------------- ~ & | ^
def
test_bitop_identities_1
(
x
):
check
(
x
&
0
==
0
,
"x & 0 != 0 for"
,
x
)
check
(
x
|
0
==
x
,
"x | 0 != x for"
,
x
)
check
(
x
^
0
==
x
,
"x ^ 0 != x for"
,
x
)
check
(
x
&
-
1
==
x
,
"x & -1 != x for"
,
x
)
check
(
x
|
-
1
==
-
1
,
"x | -1 != -1 for"
,
x
)
check
(
x
^
-
1
==
~
x
,
"x ^ -1 != ~x for"
,
x
)
check
(
x
==
~~
x
,
"x != ~~x for"
,
x
)
check
(
x
&
x
==
x
,
"x & x != x for"
,
x
)
check
(
x
|
x
==
x
,
"x | x != x for"
,
x
)
check
(
x
^
x
==
0
,
"x ^ x != 0 for"
,
x
)
check
(
x
&
~
x
==
0
,
"x & ~x != 0 for"
,
x
)
check
(
x
|
~
x
==
-
1
,
"x | ~x != -1 for"
,
x
)
check
(
x
^
~
x
==
-
1
,
"x ^ ~x != -1 for"
,
x
)
check
(
-
x
==
1
+
~
x
==
~
(
x
-
1
),
"not -x == 1 + ~x == ~(x-1) for"
,
x
)
for
n
in
range
(
2
*
SHIFT
):
p2
=
2L
**
n
check
(
x
<<
n
>>
n
==
x
,
"x << n >> n != x for"
,
x
,
n
)
check
(
x
//
p2
==
x
>>
n
,
"x // p2 != x >> n for x n p2"
,
x
,
n
,
p2
)
check
(
x
*
p2
==
x
<<
n
,
"x * p2 != x << n for x n p2"
,
x
,
n
,
p2
)
check
(
x
&
-
p2
==
x
>>
n
<<
n
==
x
&
~
(
p2
-
1
),
"not x & -p2 == x >> n << n == x & ~(p2 - 1) for x n p2"
,
x
,
n
,
p2
)
def
test_bitop_identities_2
(
x
,
y
):
check
(
x
&
y
==
y
&
x
,
"x & y != y & x for"
,
x
,
y
)
check
(
x
|
y
==
y
|
x
,
"x | y != y | x for"
,
x
,
y
)
check
(
x
^
y
==
y
^
x
,
"x ^ y != y ^ x for"
,
x
,
y
)
check
(
x
^
y
^
x
==
y
,
"x ^ y ^ x != y for"
,
x
,
y
)
check
(
x
&
y
==
~
(
~
x
|
~
y
),
"x & y != ~(~x | ~y) for"
,
x
,
y
)
check
(
x
|
y
==
~
(
~
x
&
~
y
),
"x | y != ~(~x & ~y) for"
,
x
,
y
)
check
(
x
^
y
==
(
x
|
y
)
&
~
(
x
&
y
),
"x ^ y != (x | y) & ~(x & y) for"
,
x
,
y
)
check
(
x
^
y
==
(
x
&
~
y
)
|
(
~
x
&
y
),
"x ^ y == (x & ~y) | (~x & y) for"
,
x
,
y
)
check
(
x
^
y
==
(
x
|
y
)
&
(
~
x
|
~
y
),
"x ^ y == (x | y) & (~x | ~y) for"
,
x
,
y
)
def
test_bitop_identities_3
(
x
,
y
,
z
):
check
((
x
&
y
)
&
z
==
x
&
(
y
&
z
),
"(x & y) & z != x & (y & z) for"
,
x
,
y
,
z
)
check
((
x
|
y
)
|
z
==
x
|
(
y
|
z
),
"(x | y) | z != x | (y | z) for"
,
x
,
y
,
z
)
check
((
x
^
y
)
^
z
==
x
^
(
y
^
z
),
"(x ^ y) ^ z != x ^ (y ^ z) for"
,
x
,
y
,
z
)
check
(
x
&
(
y
|
z
)
==
(
x
&
y
)
|
(
x
&
z
),
"x & (y | z) != (x & y) | (x & z) for"
,
x
,
y
,
z
)
check
(
x
|
(
y
&
z
)
==
(
x
|
y
)
&
(
x
|
z
),
"x | (y & z) != (x | y) & (x | z) for"
,
x
,
y
,
z
)
def
test_bitop_identities
(
maxdigits
=
MAXDIGITS
):
if
verbose
:
print
"long bit-operation identities"
for
x
in
special
:
test_bitop_identities_1
(
x
)
digits
=
range
(
1
,
maxdigits
+
1
)
for
lenx
in
digits
:
x
=
getran
(
lenx
)
test_bitop_identities_1
(
x
)
for
leny
in
digits
:
y
=
getran
(
leny
)
test_bitop_identities_2
(
x
,
y
)
test_bitop_identities_3
(
x
,
y
,
getran
((
lenx
+
leny
)
//
2
))
# ------------------------------------------------- hex oct repr str atol
def
slow_format
(
x
,
base
):
if
(
x
,
base
)
==
(
0
,
8
):
# this is an oddball!
return
"0L"
digits
=
[]
sign
=
0
if
x
<
0
:
sign
,
x
=
1
,
-
x
while
x
:
x
,
r
=
divmod
(
x
,
base
)
digits
.
append
(
int
(
r
))
digits
.
reverse
()
digits
=
digits
or
[
0
]
return
'-'
[:
sign
]
+
\
{
8
:
'0'
,
10
:
''
,
16
:
'0x'
}[
base
]
+
\
join
(
map
(
lambda
i
:
"0123456789ABCDEF"
[
i
],
digits
),
''
)
+
\
"L"
def
test_format_1
(
x
):
from
string
import
atol
for
base
,
mapper
in
(
8
,
oct
),
(
10
,
repr
),
(
16
,
hex
):
got
=
mapper
(
x
)
expected
=
slow_format
(
x
,
base
)
check
(
got
==
expected
,
mapper
.
__name__
,
"returned"
,
got
,
"but expected"
,
expected
,
"for"
,
x
)
check
(
atol
(
got
,
0
)
==
x
,
'atol("%s", 0) !='
%
got
,
x
)
# str() has to be checked a little differently since there's no
# trailing "L"
got
=
str
(
x
)
expected
=
slow_format
(
x
,
10
)[:
-
1
]
check
(
got
==
expected
,
mapper
.
__name__
,
"returned"
,
got
,
"but expected"
,
expected
,
"for"
,
x
)
def
test_format
(
maxdigits
=
MAXDIGITS
):
if
verbose
:
print
"long str/hex/oct/atol"
for
x
in
special
:
test_format_1
(
x
)
for
i
in
range
(
10
):
for
lenx
in
range
(
1
,
maxdigits
+
1
):
x
=
getran
(
lenx
)
test_format_1
(
x
)
# ----------------------------------------------------------------- misc
def
test_misc
(
maxdigits
=
MAXDIGITS
):
if
verbose
:
print
"long miscellaneous operations"
import
sys
# check the extremes in int<->long conversion
hugepos
=
sys
.
maxint
hugeneg
=
-
hugepos
-
1
hugepos_aslong
=
long
(
hugepos
)
hugeneg_aslong
=
long
(
hugeneg
)
check
(
hugepos
==
hugepos_aslong
,
"long(sys.maxint) != sys.maxint"
)
check
(
hugeneg
==
hugeneg_aslong
,
"long(-sys.maxint-1) != -sys.maxint-1"
)
# long -> int should not fail for hugepos_aslong or hugeneg_aslong
try
:
check
(
int
(
hugepos_aslong
)
==
hugepos
,
"converting sys.maxint to long and back to int fails"
)
except
OverflowError
:
raise
TestFailed
,
"int(long(sys.maxint)) overflowed!"
try
:
check
(
int
(
hugeneg_aslong
)
==
hugeneg
,
"converting -sys.maxint-1 to long and back to int fails"
)
except
OverflowError
:
raise
TestFailed
,
"int(long(-sys.maxint-1)) overflowed!"
# but long -> int should overflow for hugepos+1 and hugeneg-1
x
=
hugepos_aslong
+
1
try
:
y
=
int
(
x
)
except
OverflowError
:
raise
TestFailed
,
"int(long(sys.maxint) + 1) mustn't overflow"
if
not
isinstance
(
y
,
long
):
raise
TestFailed
(
"int(long(sys.maxint) + 1) should have returned long"
)
x
=
hugeneg_aslong
-
1
try
:
y
=
int
(
x
)
except
OverflowError
:
raise
TestFailed
,
"int(long(-sys.maxint-1) - 1) mustn't overflow"
if
not
isinstance
(
y
,
long
):
raise
TestFailed
(
"int(long(-sys.maxint-1) - 1) should have returned long"
)
class
long2
(
long
):
pass
x
=
long2
(
1L
<<
100
)
y
=
int
(
x
)
if
type
(
y
)
is
not
long
:
raise
TestFailed
(
"overflowing int conversion must return long not long subtype"
)
# ----------------------------------- tests of auto int->long conversion
def
test_auto_overflow
():
import
math
,
sys
if
verbose
:
print
"auto-convert int->long on overflow"
special
=
[
0
,
1
,
2
,
3
,
sys
.
maxint
-
1
,
sys
.
maxint
,
sys
.
maxint
+
1
]
sqrt
=
int
(
math
.
sqrt
(
sys
.
maxint
))
special
.
extend
([
sqrt
-
1
,
sqrt
,
sqrt
+
1
])
special
.
extend
([
-
i
for
i
in
special
])
def
checkit
(
*
args
):
# Heavy use of nested scopes here!
verify
(
got
==
expected
,
"for %r expected %r got %r"
%
(
args
,
expected
,
got
))
for
x
in
special
:
longx
=
long
(
x
)
expected
=
-
longx
got
=
-
x
checkit
(
'-'
,
x
)
for
y
in
special
:
longy
=
long
(
y
)
expected
=
longx
+
longy
got
=
x
+
y
checkit
(
x
,
'+'
,
y
)
expected
=
longx
-
longy
got
=
x
-
y
checkit
(
x
,
'-'
,
y
)
expected
=
longx
*
longy
got
=
x
*
y
checkit
(
x
,
'*'
,
y
)
if
y
:
expected
=
longx
/
longy
got
=
x
/
y
checkit
(
x
,
'/'
,
y
)
expected
=
longx
//
longy
got
=
x
//
y
checkit
(
x
,
'//'
,
y
)
expected
=
divmod
(
longx
,
longy
)
got
=
divmod
(
longx
,
longy
)
checkit
(
x
,
'divmod'
,
y
)
if
abs
(
y
)
<
5
and
not
(
x
==
0
and
y
<
0
):
expected
=
longx
**
longy
got
=
x
**
y
checkit
(
x
,
'**'
,
y
)
for
z
in
special
:
if
z
!=
0
:
if
y
>=
0
:
expected
=
pow
(
longx
,
longy
,
long
(
z
))
got
=
pow
(
x
,
y
,
z
)
checkit
(
'pow'
,
x
,
y
,
'%'
,
z
)
else
:
try
:
pow
(
longx
,
longy
,
long
(
z
))
except
TypeError
:
pass
else
:
raise
TestFailed
(
"pow%r should have raised "
"TypeError"
%
((
longx
,
longy
,
long
(
z
)),))
# ---------------------------------------- tests of long->float overflow
def
test_float_overflow
():
import
math
if
verbose
:
print
"long->float overflow"
for
x
in
-
2.0
,
-
1.0
,
0.0
,
1.0
,
2.0
:
verify
(
float
(
long
(
x
))
==
x
)
shuge
=
'12345'
*
120
huge
=
1L
<<
30000
mhuge
=
-
huge
namespace
=
{
'huge'
:
huge
,
'mhuge'
:
mhuge
,
'shuge'
:
shuge
,
'math'
:
math
}
for
test
in
[
"float(huge)"
,
"float(mhuge)"
,
"complex(huge)"
,
"complex(mhuge)"
,
"complex(huge, 1)"
,
"complex(mhuge, 1)"
,
"complex(1, huge)"
,
"complex(1, mhuge)"
,
"1. + huge"
,
"huge + 1."
,
"1. + mhuge"
,
"mhuge + 1."
,
"1. - huge"
,
"huge - 1."
,
"1. - mhuge"
,
"mhuge - 1."
,
"1. * huge"
,
"huge * 1."
,
"1. * mhuge"
,
"mhuge * 1."
,
"1. // huge"
,
"huge // 1."
,
"1. // mhuge"
,
"mhuge // 1."
,
"1. / huge"
,
"huge / 1."
,
"1. / mhuge"
,
"mhuge / 1."
,
"1. ** huge"
,
"huge ** 1."
,
"1. ** mhuge"
,
"mhuge ** 1."
,
"math.sin(huge)"
,
"math.sin(mhuge)"
,
"math.sqrt(huge)"
,
"math.sqrt(mhuge)"
,
# should do better
"math.floor(huge)"
,
"math.floor(mhuge)"
]:
class
LongTest
(
unittest
.
TestCase
):
# Get quasi-random long consisting of ndigits digits (in base BASE).
# quasi == the most-significant digit will not be 0, and the number
# is constructed to contain long strings of 0 and 1 bits. These are
# more likely than random bits to provoke digit-boundary errors.
# The sign of the number is also random.
def
getran
(
self
,
ndigits
):
self
.
assert_
(
ndigits
>
0
)
nbits_hi
=
ndigits
*
SHIFT
nbits_lo
=
nbits_hi
-
SHIFT
+
1
answer
=
0L
nbits
=
0
r
=
int
(
random
.
random
()
*
(
SHIFT
*
2
))
|
1
# force 1 bits to start
while
nbits
<
nbits_lo
:
bits
=
(
r
>>
1
)
+
1
bits
=
min
(
bits
,
nbits_hi
-
nbits
)
self
.
assert_
(
1
<=
bits
<=
SHIFT
)
nbits
=
nbits
+
bits
answer
=
answer
<<
bits
if
r
&
1
:
answer
=
answer
|
((
1
<<
bits
)
-
1
)
r
=
int
(
random
.
random
()
*
(
SHIFT
*
2
))
self
.
assert_
(
nbits_lo
<=
nbits
<=
nbits_hi
)
if
random
.
random
()
<
0.5
:
answer
=
-
answer
return
answer
# Get random long consisting of ndigits random digits (relative to base
# BASE). The sign bit is also random.
def
getran2
(
ndigits
):
answer
=
0L
for
i
in
xrange
(
ndigits
):
answer
=
(
answer
<<
SHIFT
)
|
random
.
randint
(
0
,
MASK
)
if
random
.
random
()
<
0.5
:
answer
=
-
answer
return
answer
def
check_division
(
self
,
x
,
y
):
eq
=
self
.
assertEqual
q
,
r
=
divmod
(
x
,
y
)
q2
,
r2
=
x
//
y
,
x
%
y
pab
,
pba
=
x
*
y
,
y
*
x
eq
(
pab
,
pba
,
Frm
(
"multiplication does not commute for %r and %r"
,
x
,
y
))
eq
(
q
,
q2
,
Frm
(
"divmod returns different quotient than / for %r and %r"
,
x
,
y
))
eq
(
r
,
r2
,
Frm
(
"divmod returns different mod than %% for %r and %r"
,
x
,
y
))
eq
(
x
,
q
*
y
+
r
,
Frm
(
"x != q*y + r after divmod on x=%r, y=%r"
,
x
,
y
))
if
y
>
0
:
self
.
assert_
(
0
<=
r
<
y
,
Frm
(
"bad mod from divmod on %r and %r"
,
x
,
y
))
else
:
self
.
assert_
(
y
<
r
<=
0
,
Frm
(
"bad mod from divmod on %r and %r"
,
x
,
y
))
def
test_division
(
self
):
digits
=
range
(
1
,
MAXDIGITS
+
1
)
+
range
(
KARATSUBA_CUTOFF
,
KARATSUBA_CUTOFF
+
14
)
digits
.
append
(
KARATSUBA_CUTOFF
*
3
)
for
lenx
in
digits
:
x
=
self
.
getran
(
lenx
)
for
leny
in
digits
:
y
=
self
.
getran
(
leny
)
or
1L
self
.
check_division
(
x
,
y
)
def
test_karatsuba
(
self
):
digits
=
range
(
1
,
5
)
+
range
(
KARATSUBA_CUTOFF
,
KARATSUBA_CUTOFF
+
10
)
digits
.
extend
([
KARATSUBA_CUTOFF
*
10
,
KARATSUBA_CUTOFF
*
100
])
bits
=
[
digit
*
SHIFT
for
digit
in
digits
]
# Test products of long strings of 1 bits -- (2**x-1)*(2**y-1) ==
# 2**(x+y) - 2**x - 2**y + 1, so the proper result is easy to check.
for
abits
in
bits
:
a
=
(
1L
<<
abits
)
-
1
for
bbits
in
bits
:
if
bbits
<
abits
:
continue
b
=
(
1L
<<
bbits
)
-
1
x
=
a
*
b
y
=
((
1L
<<
(
abits
+
bbits
))
-
(
1L
<<
abits
)
-
(
1L
<<
bbits
)
+
1
)
self
.
assertEqual
(
x
,
y
,
Frm
(
"bad result for a*b: a=%r, b=%r, x=%r, y=%r"
,
a
,
b
,
x
,
y
))
def
check_bitop_identities_1
(
self
,
x
):
eq
=
self
.
assertEqual
eq
(
x
&
0
,
0
,
Frm
(
"x & 0 != 0 for x=%r"
,
x
))
eq
(
x
|
0
,
x
,
Frm
(
"x | 0 != x for x=%r"
,
x
))
eq
(
x
^
0
,
x
,
Frm
(
"x ^ 0 != x for x=%r"
,
x
))
eq
(
x
&
-
1
,
x
,
Frm
(
"x & -1 != x for x=%r"
,
x
))
eq
(
x
|
-
1
,
-
1
,
Frm
(
"x | -1 != -1 for x=%r"
,
x
))
eq
(
x
^
-
1
,
~
x
,
Frm
(
"x ^ -1 != ~x for x=%r"
,
x
))
eq
(
x
,
~~
x
,
Frm
(
"x != ~~x for x=%r"
,
x
))
eq
(
x
&
x
,
x
,
Frm
(
"x & x != x for x=%r"
,
x
))
eq
(
x
|
x
,
x
,
Frm
(
"x | x != x for x=%r"
,
x
))
eq
(
x
^
x
,
0
,
Frm
(
"x ^ x != 0 for x=%r"
,
x
))
eq
(
x
&
~
x
,
0
,
Frm
(
"x & ~x != 0 for x=%r"
,
x
))
eq
(
x
|
~
x
,
-
1
,
Frm
(
"x | ~x != -1 for x=%r"
,
x
))
eq
(
x
^
~
x
,
-
1
,
Frm
(
"x ^ ~x != -1 for x=%r"
,
x
))
eq
(
-
x
,
1
+
~
x
,
Frm
(
"not -x == 1 + ~x for x=%r"
,
x
))
eq
(
-
x
,
~
(
x
-
1
),
Frm
(
"not -x == ~(x-1) forx =%r"
,
x
))
for
n
in
xrange
(
2
*
SHIFT
):
p2
=
2L
**
n
eq
(
x
<<
n
>>
n
,
x
,
Frm
(
"x << n >> n != x for x=%r, n=%r"
,
(
x
,
n
)))
eq
(
x
//
p2
,
x
>>
n
,
Frm
(
"x // p2 != x >> n for x=%r n=%r p2=%r"
,
(
x
,
n
,
p2
)))
eq
(
x
*
p2
,
x
<<
n
,
Frm
(
"x * p2 != x << n for x=%r n=%r p2=%r"
,
(
x
,
n
,
p2
)))
eq
(
x
&
-
p2
,
x
>>
n
<<
n
,
Frm
(
"not x & -p2 == x >> n << n for x=%r n=%r p2=%r"
,
(
x
,
n
,
p2
)))
eq
(
x
&
-
p2
,
x
&
~
(
p2
-
1
),
Frm
(
"not x & -p2 == x & ~(p2 - 1) for x=%r n=%r p2=%r"
,
(
x
,
n
,
p2
)))
def
check_bitop_identities_2
(
self
,
x
,
y
):
eq
=
self
.
assertEqual
eq
(
x
&
y
,
y
&
x
,
Frm
(
"x & y != y & x for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
|
y
,
y
|
x
,
Frm
(
"x | y != y | x for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
^
y
,
y
^
x
,
Frm
(
"x ^ y != y ^ x for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
^
y
^
x
,
y
,
Frm
(
"x ^ y ^ x != y for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
&
y
,
~
(
~
x
|
~
y
),
Frm
(
"x & y != ~(~x | ~y) for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
|
y
,
~
(
~
x
&
~
y
),
Frm
(
"x | y != ~(~x & ~y) for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
^
y
,
(
x
|
y
)
&
~
(
x
&
y
),
Frm
(
"x ^ y != (x | y) & ~(x & y) for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
^
y
,
(
x
&
~
y
)
|
(
~
x
&
y
),
Frm
(
"x ^ y == (x & ~y) | (~x & y) for x=%r, y=%r"
,
(
x
,
y
)))
eq
(
x
^
y
,
(
x
|
y
)
&
(
~
x
|
~
y
),
Frm
(
"x ^ y == (x | y) & (~x | ~y) for x=%r, y=%r"
,
(
x
,
y
)))
def
check_bitop_identities_3
(
self
,
x
,
y
,
z
):
eq
=
self
.
assertEqual
eq
((
x
&
y
)
&
z
,
x
&
(
y
&
z
),
Frm
(
"(x & y) & z != x & (y & z) for x=%r, y=%r, z=%r"
,
(
x
,
y
,
z
)))
eq
((
x
|
y
)
|
z
,
x
|
(
y
|
z
),
Frm
(
"(x | y) | z != x | (y | z) for x=%r, y=%r, z=%r"
,
(
x
,
y
,
z
)))
eq
((
x
^
y
)
^
z
,
x
^
(
y
^
z
),
Frm
(
"(x ^ y) ^ z != x ^ (y ^ z) for x=%r, y=%r, z=%r"
,
(
x
,
y
,
z
)))
eq
(
x
&
(
y
|
z
),
(
x
&
y
)
|
(
x
&
z
),
Frm
(
"x & (y | z) != (x & y) | (x & z) for x=%r, y=%r, z=%r"
,
(
x
,
y
,
z
)))
eq
(
x
|
(
y
&
z
),
(
x
|
y
)
&
(
x
|
z
),
Frm
(
"x | (y & z) != (x | y) & (x | z) for x=%r, y=%r, z=%r"
,
(
x
,
y
,
z
)))
def
test_bitop_identities
(
self
):
for
x
in
special
:
self
.
check_bitop_identities_1
(
x
)
digits
=
xrange
(
1
,
MAXDIGITS
+
1
)
for
lenx
in
digits
:
x
=
self
.
getran
(
lenx
)
self
.
check_bitop_identities_1
(
x
)
for
leny
in
digits
:
y
=
self
.
getran
(
leny
)
self
.
check_bitop_identities_2
(
x
,
y
)
self
.
check_bitop_identities_3
(
x
,
y
,
self
.
getran
((
lenx
+
leny
)
//
2
))
def
slow_format
(
self
,
x
,
base
):
if
(
x
,
base
)
==
(
0
,
8
):
# this is an oddball!
return
"0L"
digits
=
[]
sign
=
0
if
x
<
0
:
sign
,
x
=
1
,
-
x
while
x
:
x
,
r
=
divmod
(
x
,
base
)
digits
.
append
(
int
(
r
))
digits
.
reverse
()
digits
=
digits
or
[
0
]
return
'-'
[:
sign
]
+
\
{
8
:
'0'
,
10
:
''
,
16
:
'0x'
}[
base
]
+
\
""
.
join
(
map
(
lambda
i
:
"0123456789ABCDEF"
[
i
],
digits
))
+
"L"
def
check_format_1
(
self
,
x
):
for
base
,
mapper
in
(
8
,
oct
),
(
10
,
repr
),
(
16
,
hex
):
got
=
mapper
(
x
)
expected
=
self
.
slow_format
(
x
,
base
)
msg
=
Frm
(
"%s returned %r but expected %r for %r"
,
mapper
.
__name__
,
got
,
expected
,
x
)
self
.
assertEqual
(
got
,
expected
,
msg
)
self
.
assertEqual
(
long
(
got
,
0
),
x
,
Frm
(
'long("%s", 0) != %r'
,
got
,
x
))
# str() has to be checked a little differently since there's no
# trailing "L"
got
=
str
(
x
)
expected
=
self
.
slow_format
(
x
,
10
)[:
-
1
]
msg
=
Frm
(
"%s returned %r but expected %r for %r"
,
mapper
.
__name__
,
got
,
expected
,
x
)
self
.
assertEqual
(
got
,
expected
,
msg
)
def
test_format
(
self
):
for
x
in
special
:
self
.
check_format_1
(
x
)
for
i
in
xrange
(
10
):
for
lenx
in
xrange
(
1
,
MAXDIGITS
+
1
):
x
=
self
.
getran
(
lenx
)
self
.
check_format_1
(
x
)
def
test_misc
(
self
):
import
sys
# check the extremes in int<->long conversion
hugepos
=
sys
.
maxint
hugeneg
=
-
hugepos
-
1
hugepos_aslong
=
long
(
hugepos
)
hugeneg_aslong
=
long
(
hugeneg
)
self
.
assertEqual
(
hugepos
,
hugepos_aslong
,
"long(sys.maxint) != sys.maxint"
)
self
.
assertEqual
(
hugeneg
,
hugeneg_aslong
,
"long(-sys.maxint-1) != -sys.maxint-1"
)
# long -> int should not fail for hugepos_aslong or hugeneg_aslong
try
:
try
:
eval
(
test
,
namespace
)
self
.
assertEqual
(
int
(
hugepos_aslong
),
hugepos
,
"converting sys.maxint to long and back to int fails"
)
except
OverflowError
:
except
OverflowError
:
pass
self
.
fail
(
"int(long(sys.maxint)) overflowed!"
)
else
:
try
:
raise
TestFailed
(
"expected OverflowError from %s"
%
test
)
self
.
assertEqual
(
int
(
hugeneg_aslong
),
hugeneg
,
"converting -sys.maxint-1 to long and back to int fails"
)
# XXX Perhaps float(shuge) can raise OverflowError on some box?
except
OverflowError
:
# The comparison should not.
self
.
fail
(
"int(long(-sys.maxint-1)) overflowed!"
)
if
float
(
shuge
)
==
int
(
shuge
):
raise
TestFailed
(
"float(shuge) should not equal int(shuge)"
)
# ---------------------------------------------- test huge log and log10
def
test_logs
():
import
math
if
verbose
:
print
"log and log10"
LOG10E
=
math
.
log10
(
math
.
e
)
for
exp
in
range
(
10
)
+
[
100
,
1000
,
10000
]:
value
=
10
**
exp
log10
=
math
.
log10
(
value
)
verify
(
fcmp
(
log10
,
exp
)
==
0
)
# log10(value) == exp, so log(value) == log10(value)/log10(e) ==
# exp/LOG10E
expected
=
exp
/
LOG10E
log
=
math
.
log
(
value
)
verify
(
fcmp
(
log
,
expected
)
==
0
)
for
bad
in
-
(
1L
<<
10000
),
-
2L
,
0L
:
# but long -> int should overflow for hugepos+1 and hugeneg-1
x
=
hugepos_aslong
+
1
try
:
try
:
math
.
log
(
bad
)
y
=
int
(
x
)
raise
TestFailed
(
"expected ValueError from log(<= 0)"
)
except
OverflowError
:
except
ValueError
:
self
.
fail
(
"int(long(sys.maxint) + 1) mustn't overflow"
)
pass
self
.
assert_
(
isinstance
(
y
,
long
),
"int(long(sys.maxint) + 1) should have returned long"
)
x
=
hugeneg_aslong
-
1
try
:
try
:
math
.
log10
(
bad
)
y
=
int
(
x
)
raise
TestFailed
(
"expected ValueError from log10(<= 0)"
)
except
OverflowError
:
except
ValueError
:
self
.
fail
(
"int(long(-sys.maxint-1) - 1) mustn't overflow"
)
self
.
assert_
(
isinstance
(
y
,
long
),
"int(long(-sys.maxint-1) - 1) should have returned long"
)
class
long2
(
long
):
pass
pass
x
=
long2
(
1L
<<
100
)
y
=
int
(
x
)
self
.
assert_
(
type
(
y
)
is
long
,
"overflowing int conversion must return long not long subtype"
)
# ----------------------------------------------- test mixed comparisons
# ----------------------------------- tests of auto int->long conversion
def
test_mixed_compares
():
def
test_auto_overflow
(
self
):
import
math
import
math
,
sys
import
sys
special
=
[
0
,
1
,
2
,
3
,
sys
.
maxint
-
1
,
sys
.
maxint
,
sys
.
maxint
+
1
]
if
verbose
:
sqrt
=
int
(
math
.
sqrt
(
sys
.
maxint
))
print
"mixed comparisons"
special
.
extend
([
sqrt
-
1
,
sqrt
,
sqrt
+
1
])
special
.
extend
([
-
i
for
i
in
special
])
# We're mostly concerned with that mixing floats and longs does the
# right stuff, even when longs are too large to fit in a float.
def
checkit
(
*
args
):
# The safest way to check the results is to use an entirely different
# Heavy use of nested scopes here!
# method, which we do here via a skeletal rational class (which
self
.
assertEqual
(
got
,
expected
,
# represents all Python ints, longs and floats exactly).
Frm
(
"for %r expected %r got %r"
,
args
,
expected
,
got
))
class
Rat
:
def
__init__
(
self
,
value
):
for
x
in
special
:
if
isinstance
(
value
,
(
int
,
long
)):
longx
=
long
(
x
)
self
.
n
=
value
self
.
d
=
1
expected
=
-
longx
got
=
-
x
elif
isinstance
(
value
,
float
):
checkit
(
'-'
,
x
)
# Convert to exact rational equivalent.
f
,
e
=
math
.
frexp
(
abs
(
value
))
for
y
in
special
:
assert
f
==
0
or
0.5
<=
f
<
1.0
longy
=
long
(
y
)
# |value| = f * 2**e exactly
expected
=
longx
+
longy
# Suck up CHUNK bits at a time; 28 is enough so that we suck
got
=
x
+
y
# up all bits in 2 iterations for all known binary double-
checkit
(
x
,
'+'
,
y
)
# precision formats, and small enough to fit in an int.
CHUNK
=
28
expected
=
longx
-
longy
top
=
0
got
=
x
-
y
# invariant: |value| = (top + f) * 2**e exactly
checkit
(
x
,
'-'
,
y
)
while
f
:
f
=
math
.
ldexp
(
f
,
CHUNK
)
expected
=
longx
*
longy
digit
=
int
(
f
)
got
=
x
*
y
assert
digit
>>
CHUNK
==
0
checkit
(
x
,
'*'
,
y
)
top
=
(
top
<<
CHUNK
)
|
digit
f
-=
digit
if
y
:
assert
0.0
<=
f
<
1.0
expected
=
longx
/
longy
e
-=
CHUNK
got
=
x
/
y
checkit
(
x
,
'/'
,
y
)
# Now |value| = top * 2**e exactly.
if
e
>=
0
:
expected
=
longx
//
longy
n
=
top
<<
e
got
=
x
//
y
d
=
1
checkit
(
x
,
'//'
,
y
)
expected
=
divmod
(
longx
,
longy
)
got
=
divmod
(
longx
,
longy
)
checkit
(
x
,
'divmod'
,
y
)
if
abs
(
y
)
<
5
and
not
(
x
==
0
and
y
<
0
):
expected
=
longx
**
longy
got
=
x
**
y
checkit
(
x
,
'**'
,
y
)
for
z
in
special
:
if
z
!=
0
:
if
y
>=
0
:
expected
=
pow
(
longx
,
longy
,
long
(
z
))
got
=
pow
(
x
,
y
,
z
)
checkit
(
'pow'
,
x
,
y
,
'%'
,
z
)
else
:
self
.
assertRaises
(
TypeError
,
pow
,
longx
,
longy
,
long
(
z
))
def
test_float_overflow
(
self
):
import
math
for
x
in
-
2.0
,
-
1.0
,
0.0
,
1.0
,
2.0
:
self
.
assertEqual
(
float
(
long
(
x
)),
x
)
shuge
=
'12345'
*
120
huge
=
1L
<<
30000
mhuge
=
-
huge
namespace
=
{
'huge'
:
huge
,
'mhuge'
:
mhuge
,
'shuge'
:
shuge
,
'math'
:
math
}
for
test
in
[
"float(huge)"
,
"float(mhuge)"
,
"complex(huge)"
,
"complex(mhuge)"
,
"complex(huge, 1)"
,
"complex(mhuge, 1)"
,
"complex(1, huge)"
,
"complex(1, mhuge)"
,
"1. + huge"
,
"huge + 1."
,
"1. + mhuge"
,
"mhuge + 1."
,
"1. - huge"
,
"huge - 1."
,
"1. - mhuge"
,
"mhuge - 1."
,
"1. * huge"
,
"huge * 1."
,
"1. * mhuge"
,
"mhuge * 1."
,
"1. // huge"
,
"huge // 1."
,
"1. // mhuge"
,
"mhuge // 1."
,
"1. / huge"
,
"huge / 1."
,
"1. / mhuge"
,
"mhuge / 1."
,
"1. ** huge"
,
"huge ** 1."
,
"1. ** mhuge"
,
"mhuge ** 1."
,
"math.sin(huge)"
,
"math.sin(mhuge)"
,
"math.sqrt(huge)"
,
"math.sqrt(mhuge)"
,
# should do better
"math.floor(huge)"
,
"math.floor(mhuge)"
]:
self
.
assertRaises
(
OverflowError
,
eval
,
test
,
namespace
)
# XXX Perhaps float(shuge) can raise OverflowError on some box?
# The comparison should not.
self
.
assertNotEqual
(
float
(
shuge
),
int
(
shuge
),
"float(shuge) should not equal int(shuge)"
)
def
test_logs
(
self
):
import
math
LOG10E
=
math
.
log10
(
math
.
e
)
for
exp
in
range
(
10
)
+
[
100
,
1000
,
10000
]:
value
=
10
**
exp
log10
=
math
.
log10
(
value
)
self
.
assertAlmostEqual
(
log10
,
exp
)
# log10(value) == exp, so log(value) == log10(value)/log10(e) ==
# exp/LOG10E
expected
=
exp
/
LOG10E
log
=
math
.
log
(
value
)
self
.
assertAlmostEqual
(
log
,
expected
)
for
bad
in
-
(
1L
<<
10000
),
-
2L
,
0L
:
self
.
assertRaises
(
ValueError
,
math
.
log
,
bad
)
self
.
assertRaises
(
ValueError
,
math
.
log10
,
bad
)
def
test_mixed_compares
(
self
):
eq
=
self
.
assertEqual
import
math
import
sys
# We're mostly concerned with that mixing floats and longs does the
# right stuff, even when longs are too large to fit in a float.
# The safest way to check the results is to use an entirely different
# method, which we do here via a skeletal rational class (which
# represents all Python ints, longs and floats exactly).
class
Rat
:
def
__init__
(
self
,
value
):
if
isinstance
(
value
,
(
int
,
long
)):
self
.
n
=
value
self
.
d
=
1
elif
isinstance
(
value
,
float
):
# Convert to exact rational equivalent.
f
,
e
=
math
.
frexp
(
abs
(
value
))
assert
f
==
0
or
0.5
<=
f
<
1.0
# |value| = f * 2**e exactly
# Suck up CHUNK bits at a time; 28 is enough so that we suck
# up all bits in 2 iterations for all known binary double-
# precision formats, and small enough to fit in an int.
CHUNK
=
28
top
=
0
# invariant: |value| = (top + f) * 2**e exactly
while
f
:
f
=
math
.
ldexp
(
f
,
CHUNK
)
digit
=
int
(
f
)
assert
digit
>>
CHUNK
==
0
top
=
(
top
<<
CHUNK
)
|
digit
f
-=
digit
assert
0.0
<=
f
<
1.0
e
-=
CHUNK
# Now |value| = top * 2**e exactly.
if
e
>=
0
:
n
=
top
<<
e
d
=
1
else
:
n
=
top
d
=
1
<<
-
e
if
value
<
0
:
n
=
-
n
self
.
n
=
n
self
.
d
=
d
assert
float
(
n
)
/
float
(
d
)
==
value
else
:
else
:
n
=
top
raise
TypeError
(
"can't deal with %r"
%
val
)
d
=
1
<<
-
e
if
value
<
0
:
def
__cmp__
(
self
,
other
):
n
=
-
n
if
not
isinstance
(
other
,
Rat
):
self
.
n
=
n
other
=
Rat
(
other
)
self
.
d
=
d
return
cmp
(
self
.
n
*
other
.
d
,
self
.
d
*
other
.
n
)
assert
float
(
n
)
/
float
(
d
)
==
value
cases
=
[
0
,
0.001
,
0.99
,
1.0
,
1.5
,
1e20
,
1e200
]
else
:
# 2**48 is an important boundary in the internals. 2**53 is an
raise
TypeError
(
"can't deal with %r"
%
val
)
# important boundary for IEEE double precision.
for
t
in
2.0
**
48
,
2.0
**
50
,
2.0
**
53
:
def
__cmp__
(
self
,
other
):
cases
.
extend
([
t
-
1.0
,
t
-
0.3
,
t
,
t
+
0.3
,
t
+
1.0
,
if
not
isinstance
(
other
,
Rat
):
long
(
t
-
1
),
long
(
t
),
long
(
t
+
1
)])
other
=
Rat
(
other
)
cases
.
extend
([
0
,
1
,
2
,
sys
.
maxint
,
float
(
sys
.
maxint
)])
return
cmp
(
self
.
n
*
other
.
d
,
self
.
d
*
other
.
n
)
# 1L<<20000 should exceed all double formats. long(1e200) is to
# check that we get equality with 1e200 above.
cases
=
[
0
,
0.001
,
0.99
,
1.0
,
1.5
,
1e20
,
1e200
]
t
=
long
(
1e200
)
# 2**48 is an important boundary in the internals. 2**53 is an
cases
.
extend
([
0L
,
1L
,
2L
,
1L
<<
20000
,
t
-
1
,
t
,
t
+
1
])
# important boundary for IEEE double precision.
cases
.
extend
([
-
x
for
x
in
cases
])
for
t
in
2.0
**
48
,
2.0
**
50
,
2.0
**
53
:
for
x
in
cases
:
cases
.
extend
([
t
-
1.0
,
t
-
0.3
,
t
,
t
+
0.3
,
t
+
1.0
,
Rx
=
Rat
(
x
)
long
(
t
-
1
),
long
(
t
),
long
(
t
+
1
)])
for
y
in
cases
:
cases
.
extend
([
0
,
1
,
2
,
sys
.
maxint
,
float
(
sys
.
maxint
)])
Ry
=
Rat
(
y
)
# 1L<<20000 should exceed all double formats. long(1e200) is to
Rcmp
=
cmp
(
Rx
,
Ry
)
# check that we get equality with 1e200 above.
xycmp
=
cmp
(
x
,
y
)
t
=
long
(
1e200
)
eq
(
Rcmp
,
xycmp
,
Frm
(
"%r %r %d %d"
,
x
,
y
,
Rcmp
,
xycmp
))
cases
.
extend
([
0L
,
1L
,
2L
,
1L
<<
20000
,
t
-
1
,
t
,
t
+
1
])
eq
(
x
==
y
,
Rcmp
==
0
,
Frm
(
"%r == %r %d"
,
x
,
y
,
Rcmp
))
cases
.
extend
([
-
x
for
x
in
cases
])
eq
(
x
!=
y
,
Rcmp
!=
0
,
Frm
(
"%r != %r %d"
,
x
,
y
,
Rcmp
))
for
x
in
cases
:
eq
(
x
<
y
,
Rcmp
<
0
,
Frm
(
"%r < %r %d"
,
x
,
y
,
Rcmp
))
Rx
=
Rat
(
x
)
eq
(
x
<=
y
,
Rcmp
<=
0
,
Frm
(
"%r <= %r %d"
,
x
,
y
,
Rcmp
))
for
y
in
cases
:
eq
(
x
>
y
,
Rcmp
>
0
,
Frm
(
"%r > %r %d"
,
x
,
y
,
Rcmp
))
Ry
=
Rat
(
y
)
eq
(
x
>=
y
,
Rcmp
>=
0
,
Frm
(
"%r >= %r %d"
,
x
,
y
,
Rcmp
))
Rcmp
=
cmp
(
Rx
,
Ry
)
xycmp
=
cmp
(
x
,
y
)
def
test_main
():
if
Rcmp
!=
xycmp
:
test_support
.
run_unittest
(
LongTest
)
raise
TestFailed
(
'%r %r %d %d'
%
(
x
,
y
,
Rcmp
,
xycmp
))
if
(
x
==
y
)
!=
(
Rcmp
==
0
):
if
__name__
==
"__main__"
:
raise
TestFailed
(
'%r == %r %d'
%
(
x
,
y
,
Rcmp
))
test_main
()
if
(
x
!=
y
)
!=
(
Rcmp
!=
0
):
raise
TestFailed
(
'%r != %r %d'
%
(
x
,
y
,
Rcmp
))
if
(
x
<
y
)
!=
(
Rcmp
<
0
):
raise
TestFailed
(
'%r < %r %d'
%
(
x
,
y
,
Rcmp
))
if
(
x
<=
y
)
!=
(
Rcmp
<=
0
):
raise
TestFailed
(
'%r <= %r %d'
%
(
x
,
y
,
Rcmp
))
if
(
x
>
y
)
!=
(
Rcmp
>
0
):
raise
TestFailed
(
'%r > %r %d'
%
(
x
,
y
,
Rcmp
))
if
(
x
>=
y
)
!=
(
Rcmp
>=
0
):
raise
TestFailed
(
'%r >= %r %d'
%
(
x
,
y
,
Rcmp
))
# ---------------------------------------------------------------- do it
test_division
()
test_karatsuba
()
test_bitop_identities
()
test_format
()
test_misc
()
test_auto_overflow
()
test_float_overflow
()
test_logs
()
test_mixed_compares
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment