Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Xavier Thompson
cython
Commits
44694afc
Commit
44694afc
authored
Apr 03, 2015
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
inline PyLong type conversion also for very large integer types and test with int128 in gcc
parent
fdac73d6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
140 additions
and
5 deletions
+140
-5
Cython/Utility/TypeConversion.c
Cython/Utility/TypeConversion.c
+12
-4
runtests.py
runtests.py
+9
-1
tests/run/int128.pyx
tests/run/int128.pyx
+119
-0
No files found.
Cython/Utility/TypeConversion.c
View file @
44694afc
...
...
@@ -602,8 +602,12 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
case
1
:
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
digit
,
digits
[
0
])
{{
for
_size
in
(
2
,
3
,
4
)}}
case
{{
_size
}}
:
if
((
8
*
sizeof
({{
TYPE
}})
>
{{
_size
-
1
}}
*
PyLong_SHIFT
)
&&
(
8
*
sizeof
(
unsigned
long
)
>
{{
_size
}}
*
PyLong_SHIFT
))
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
unsigned
long
,
{{
pylong_join
(
_size
,
'
digits
'
)}})
if
(
8
*
sizeof
({{
TYPE
}})
>
{{
_size
-
1
}}
*
PyLong_SHIFT
)
{
if
(
8
*
sizeof
(
unsigned
long
)
>
{{
_size
}}
*
PyLong_SHIFT
)
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
unsigned
long
,
{{
pylong_join
(
_size
,
'
digits
'
)}})
}
else
if
(
8
*
sizeof
({{
TYPE
}})
>=
{{
_size
}}
*
PyLong_SHIFT
)
{
return
{{
pylong_join
(
_size
,
'
digits
'
,
TYPE
)}};
}
}
break
;
{{
endfor
}}
...
...
@@ -639,8 +643,12 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
{{
for
_size
in
(
2
,
3
,
4
)}}
{{
for
_case
in
(
-
_size
,
_size
)}}
case
{{
_case
}}
:
if
((
8
*
sizeof
({{
TYPE
}})
>
{{
_size
if
_case
<
0
else
_size
-
1
}}
*
PyLong_SHIFT
)
&&
(
8
*
sizeof
(
unsigned
long
)
>
{{
_size
}}
*
PyLong_SHIFT
))
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
{{
'
long
'
if
_case
<
0
else
'
unsigned
long
'
}},
{{
'
-
(
long
)
'
if
_case
<
0
else
''
}}{{
pylong_join
(
_size
,
'
digits
'
)}})
if
(
8
*
sizeof
({{
TYPE
}}){{
'
-
1
'
if
_case
<
0
else
''
}}
>
{{
_size
-
1
}}
*
PyLong_SHIFT
)
{
if
(
8
*
sizeof
(
unsigned
long
)
>
{{
_size
}}
*
PyLong_SHIFT
)
{
__PYX_VERIFY_RETURN_INT
({{
TYPE
}},
{{
'
long
'
if
_case
<
0
else
'
unsigned
long
'
}},
{{
'
-
(
long
)
'
if
_case
<
0
else
''
}}{{
pylong_join
(
_size
,
'
digits
'
)}})
}
else
if
(
8
*
sizeof
({{
TYPE
}})
-
1
>
{{
_size
}}
*
PyLong_SHIFT
)
{
return
{{
'-'
if
_case
<
0
else
''
}}{{
pylong_join
(
_size
,
'
digits
'
,
TYPE
)}};
}
}
break
;
{{
endfor
}}
...
...
runtests.py
View file @
44694afc
...
...
@@ -271,6 +271,10 @@ def get_openmp_compiler_flags(language):
if not gcc_version:
return None # not gcc - FIXME: do something about other compilers
# gcc defines "__int128_t", assume that at least all 64 bit architectures have it
global COMPILER_HAS_INT128
COMPILER_HAS_INT128 = getattr(sys, 'maxsize', getattr(sys, 'maxint', 0)) > 2**60
compiler_version = gcc_version.group(1)
if compiler_version and compiler_version.split('.') >= ['4', '2']:
return '-fopenmp', '-fopenmp'
...
...
@@ -280,6 +284,8 @@ try:
except locale.Error:
pass
COMPILER = None
COMPILER_HAS_INT128 = False
OPENMP_C_COMPILER_FLAGS = get_openmp_compiler_flags('c')
OPENMP_CPP_COMPILER_FLAGS = get_openmp_compiler_flags('cpp')
...
...
@@ -327,7 +333,6 @@ VER_DEP_MODULES = {
]),
}
COMPILER = None
INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ]
CFLAGS = os.getenv('CFLAGS', '').split()
CCACHE = os.getenv('CYTHON_RUNTESTS_CCACHE', '').split()
...
...
@@ -1941,6 +1946,9 @@ def runtests(options, cmd_args, coverage=None):
if options.exclude:
exclude_selectors += [ string_selector(r) for r in options.exclude ]
if not COMPILER_HAS_INT128 or not IS_CPYTHON:
exclude_selectors += [RegExSelector('int128')]
if options.shard_num > -1:
exclude_selectors.append(ShardExcludeSelector(options.shard_num, options.shard_count))
...
...
tests/run/int128.pyx
0 → 100644
View file @
44694afc
cdef
extern
from
*
:
ctypedef
long
long
int128_t
"__int128_t"
ctypedef
unsigned
long
long
uint128_t
"__uint128_t"
def
bigint
(
x
):
print
(
str
(
x
).
rstrip
(
'L'
))
def
unsigned_conversion
(
x
):
"""
>>> bigint(unsigned_conversion(0))
0
>>> bigint(unsigned_conversion(2))
2
>>> unsigned_conversion(-2) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: can't convert negative value to ...uint128_t
>>> unsigned_conversion(-2**120) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: can't convert negative value to ...uint128_t
>>> unsigned_conversion(-2**127) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: can't convert negative value to ...uint128_t
>>> unsigned_conversion(-2**128) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: can't convert negative value to ...uint128_t
>>> bigint(unsigned_conversion(2**20))
1048576
>>> bigint(unsigned_conversion(2**30-1))
1073741823
>>> bigint(unsigned_conversion(2**30))
1073741824
>>> bigint(unsigned_conversion(2**30+1))
1073741825
>>> bigint(2**60)
1152921504606846976
>>> bigint(unsigned_conversion(2**60-1))
1152921504606846975
>>> bigint(unsigned_conversion(2**60))
1152921504606846976
>>> bigint(unsigned_conversion(2**60+1))
1152921504606846977
>>> bigint(2**64)
18446744073709551616
>>> bigint(unsigned_conversion(2**64))
18446744073709551616
>>> bigint(2**120)
1329227995784915872903807060280344576
>>> bigint(unsigned_conversion(2**120))
1329227995784915872903807060280344576
>>> bigint(2**128-1)
340282366920938463463374607431768211455
>>> bigint(unsigned_conversion(2**128-1))
340282366920938463463374607431768211455
>>> bigint(unsigned_conversion(2**128)) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: ... too big to convert
"""
cdef
uint128_t
n
=
x
return
n
def
signed_conversion
(
x
):
"""
>>> bigint(signed_conversion(0))
0
>>> bigint(signed_conversion(2))
2
>>> bigint(signed_conversion(-2))
-2
>>> bigint(signed_conversion(2**20))
1048576
>>> bigint(signed_conversion(2**32))
4294967296
>>> bigint(2**64)
18446744073709551616
>>> bigint(signed_conversion(2**64))
18446744073709551616
>>> bigint(signed_conversion(-2**64))
-18446744073709551616
>>> bigint(2**118)
332306998946228968225951765070086144
>>> bigint(signed_conversion(2**118))
332306998946228968225951765070086144
>>> bigint(signed_conversion(-2**118))
-332306998946228968225951765070086144
>>> bigint(2**120)
1329227995784915872903807060280344576
>>> bigint(signed_conversion(2**120))
1329227995784915872903807060280344576
>>> bigint(signed_conversion(-2**120))
-1329227995784915872903807060280344576
>>> bigint(2**127-1)
170141183460469231731687303715884105727
>>> bigint(signed_conversion(2**127-2))
170141183460469231731687303715884105726
>>> bigint(signed_conversion(2**127-1))
170141183460469231731687303715884105727
>>> bigint(signed_conversion(2**127)) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: ... too big to convert
>>> bigint(signed_conversion(-2**127))
-170141183460469231731687303715884105728
>>> bigint(signed_conversion(-2**127-1)) # doctest: +ELLIPSIS
Traceback (most recent call last):
OverflowError: ... too big to convert
"""
cdef
int128_t
n
=
x
return
n
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