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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
b9fc5d92
Commit
b9fc5d92
authored
Dec 08, 2009
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
translate Python float calculations into C doubles
parent
c7dbcf9a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
59 additions
and
20 deletions
+59
-20
Cython/Compiler/Builtin.py
Cython/Compiler/Builtin.py
+2
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+14
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+4
-0
Cython/Compiler/TypeInference.py
Cython/Compiler/TypeInference.py
+8
-4
tests/run/int_float_builtins_as_casts_T400.pyx
tests/run/int_float_builtins_as_casts_T400.pyx
+12
-13
tests/run/type_inference.pyx
tests/run/type_inference.pyx
+19
-0
No files found.
Cython/Compiler/Builtin.py
View file @
b9fc5d92
...
...
@@ -414,7 +414,7 @@ def init_builtins():
init_builtin_types
()
init_builtin_structs
()
global
list_type
,
tuple_type
,
dict_type
,
set_type
,
type_type
global
bytes_type
,
str_type
,
unicode_type
global
bytes_type
,
str_type
,
unicode_type
,
float_type
type_type
=
builtin_scope
.
lookup
(
'type'
).
type
list_type
=
builtin_scope
.
lookup
(
'list'
).
type
tuple_type
=
builtin_scope
.
lookup
(
'tuple'
).
type
...
...
@@ -423,5 +423,6 @@ def init_builtins():
bytes_type
=
builtin_scope
.
lookup
(
'bytes'
).
type
str_type
=
builtin_scope
.
lookup
(
'str'
).
type
unicode_type
=
builtin_scope
.
lookup
(
'unicode'
).
type
float_type
=
builtin_scope
.
lookup
(
'float'
).
type
init_builtins
()
Cython/Compiler/ExprNodes.py
View file @
b9fc5d92
...
...
@@ -2412,7 +2412,9 @@ class SimpleCallNode(CallNode):
if
result_type
.
is_extension_type
:
return
result_type
elif
result_type
.
is_builtin_type
:
if
function
.
entry
.
name
in
Builtin
.
types_that_construct_their_instance
:
if
function
.
entry
.
name
==
'float'
:
return
PyrexTypes
.
c_double_type
elif
function
.
entry
.
name
in
Builtin
.
types_that_construct_their_instance
:
return
result_type
return
py_object_type
...
...
@@ -2447,7 +2449,17 @@ class SimpleCallNode(CallNode):
self
.
arg_tuple
=
TupleNode
(
self
.
pos
,
args
=
self
.
args
)
self
.
arg_tuple
.
analyse_types
(
env
)
self
.
args
=
None
if
function
.
is_name
and
function
.
type_entry
:
if
func_type
is
Builtin
.
type_type
and
function
.
entry
.
is_builtin
and
\
function
.
entry
.
name
in
Builtin
.
types_that_construct_their_instance
:
# calling a builtin type that returns a specific object type
if
function
.
entry
.
name
==
'float'
:
# the following will come true later on in a transform
self
.
type
=
PyrexTypes
.
c_double_type
self
.
result_ctype
=
PyrexTypes
.
c_double_type
else
:
self
.
type
=
Builtin
.
builtin_types
[
function
.
entry
.
name
]
self
.
result_ctype
=
py_object_type
elif
function
.
is_name
and
function
.
type_entry
:
# We are calling an extension type constructor. As
# long as we do not support __new__(), the result type
# is clear
...
...
Cython/Compiler/PyrexTypes.py
View file @
b9fc5d92
...
...
@@ -2031,6 +2031,10 @@ def spanning_type(type1, type2):
return
type1
elif
type1
.
is_numeric
and
type2
.
is_numeric
:
return
widest_numeric_type
(
type1
,
type2
)
elif
type1
.
is_builtin_type
and
type1
.
name
==
'float'
and
type2
.
is_numeric
:
return
widest_numeric_type
(
c_double_type
,
type2
)
elif
type2
.
is_builtin_type
and
type2
.
name
==
'float'
and
type1
.
is_numeric
:
return
widest_numeric_type
(
type1
,
c_double_type
)
elif
type1
.
is_pyobject
^
type2
.
is_pyobject
:
return
py_object_type
elif
type1
.
assignable_from
(
type2
):
...
...
Cython/Compiler/TypeInference.py
View file @
b9fc5d92
...
...
@@ -191,16 +191,20 @@ class SimpleAssignmentTypeInferer:
entry
.
type
=
py_object_type
def
find_safe_type
(
result_type
,
which_types_to_infer
):
if
which_types_to_infer
==
'none'
:
return
py_object_type
if
result_type
in
(
PyrexTypes
.
c_double_type
,
PyrexTypes
.
c_float_type
,
Builtin
.
float_type
):
# Python's float type is just a C double, so it's safe to
# use the C type instead
return
PyrexTypes
.
c_double_type
if
which_types_to_infer
==
'all'
:
return
result_type
elif
which_types_to_infer
==
'safe'
:
if
result_type
.
is_pyobject
:
# any specific Python type is always safe to infer
return
result_type
elif
result_type
in
(
PyrexTypes
.
c_double_type
,
PyrexTypes
.
c_float_type
):
# Python's float type is just a C double, so it's safe to
# use the C type instead
return
PyrexTypes
.
c_double_type
elif
result_type
is
PyrexTypes
.
c_bint_type
:
# 'bint' should behave exactly like Python's bool type ...
return
PyrexTypes
.
c_bint_type
...
...
tests/run/int_float_builtins_as_casts_T400.pyx
View file @
b9fc5d92
...
...
@@ -37,17 +37,17 @@ def int_to_pyssizet_int(int x):
cdef
Py_ssize_t
r
=
int
(
x
)
return
r
@
cython
.
test_assert_path_exists
(
"//SingleAssignmentNode/CastNode"
)
@
cython
.
test_fail_if_path_exists
(
"//SimpleCallNode"
)
def
double_to_pyssizet_float
(
double
x
):
"""
>>> double_to_pyssizet_float(4.1)
4
>>> double_to_pyssizet_float(4)
4
"""
cdef
Py_ssize_t
r
=
float
(
x
)
return
r
##
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
##
@cython.test_fail_if_path_exists("//SimpleCallNode")
##
def double_to_pyssizet_float(double x):
##
"""
##
>>> double_to_pyssizet_float(4.1)
##
4
##
>>> double_to_pyssizet_float(4)
##
4
##
"""
##
cdef Py_ssize_t r = float(x)
##
return r
@
cython
.
test_assert_path_exists
(
"//SingleAssignmentNode/CastNode"
)
@
cython
.
test_fail_if_path_exists
(
"//SimpleCallNode"
)
...
...
@@ -89,8 +89,7 @@ def short_to_double_int(short x):
cdef
double
r
=
int
(
x
)
return
r
@
cython
.
test_fail_if_path_exists
(
"//SimpleCallNode"
,
"//SingleAssignmentNode/CastNode"
)
@
cython
.
test_fail_if_path_exists
(
"//SimpleCallNode"
)
def
float_to_float_float
(
float
x
):
"""
>>> 4.05 < float_to_float_float(4.1) < 4.15
...
...
tests/run/type_inference.pyx
View file @
b9fc5d92
...
...
@@ -149,6 +149,25 @@ def loop():
assert
typeof
(
a
)
==
"long"
@
infer_types
(
'safe'
)
def
double_inference
():
"""
>>> values, types = double_inference()
>>> values == (1.0, 1.0*2, 1.0*2.0+2.0*2.0, 1.0*2.0)
True
>>> types
('double', 'double', 'double', 'Python object')
"""
d_a
=
1.0
d_b
=
d_a
*
float
(
2
)
d_c
=
d_a
*
float
(
some_float_value
())
+
d_b
*
float
(
some_float_value
())
o_d
=
d_a
*
some_float_value
()
return
(
d_a
,
d_b
,
d_c
,
o_d
),
(
typeof
(
d_a
),
typeof
(
d_b
),
typeof
(
d_c
),
typeof
(
o_d
))
cdef
object
some_float_value
():
return
2.0
@
cython
.
test_fail_if_path_exists
(
'//NameNode[@type.is_pyobject = True]'
)
@
cython
.
test_assert_path_exists
(
'//InPlaceAssignmentNode/NameNode'
,
'//NameNode[@type.is_pyobject]'
,
...
...
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