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
Boxiang Sun
cython
Commits
a60c7801
Commit
a60c7801
authored
Mar 25, 2009
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cdivision pragma as specified for CEP 516
parent
4f8ba2bf
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
102 additions
and
28 deletions
+102
-28
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+80
-20
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+8
-8
tests/run/cdivision_CEP_516.pyx
tests/run/cdivision_CEP_516.pyx
+14
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
a60c7801
...
...
@@ -4229,14 +4229,27 @@ class MulNode(NumBinopNode):
return
NumBinopNode
.
is_py_operation
(
self
)
class
FloorDivNode
(
NumBinopNode
):
# '//' operator.
class
DivNode
(
NumBinopNode
):
# '/' or '//' operator.
def
generate_evaluation_code
(
self
,
code
):
self
.
cdivision
=
(
code
.
globalstate
.
directives
[
'cdivision'
]
or
not
self
.
type
.
signed
or
self
.
type
.
is_float
)
if
not
self
.
cdivision
:
code
.
globalstate
.
use_utility_code
(
div_utility_code
.
specialize
(
self
.
type
))
NumBinopNode
.
generate_evaluation_code
(
self
,
code
)
def
calculate_result_code
(
self
):
return
"(%s %s %s)"
%
(
self
.
operand1
.
result
(),
"/"
,
# c division is by default floor-div
self
.
operand2
.
result
())
if
self
.
cdivision
:
return
"(%s / %s)"
%
(
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
else
:
return
"__Pyx_div_%s(%s, %s)"
%
(
self
.
type
.
specalization_name
(),
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
class
ModNode
(
NumBinopNode
):
...
...
@@ -4247,15 +4260,31 @@ class ModNode(NumBinopNode):
or
self
.
operand2
.
type
.
is_string
or
NumBinopNode
.
is_py_operation
(
self
))
def
generate_evaluation_code
(
self
,
code
):
self
.
cdivision
=
code
.
globalstate
.
directives
[
'cdivision'
]
or
not
self
.
type
.
signed
if
not
self
.
cdivision
:
math_h_modifier
=
getattr
(
self
.
type
,
'math_h_modifier'
,
'__Pyx_INT'
)
if
self
.
type
.
is_int
:
code
.
globalstate
.
use_utility_code
(
mod_int_helper_macro
)
code
.
globalstate
.
use_utility_code
(
mod_utility_code
.
specialize
(
self
.
type
,
math_h_modifier
=
math_h_modifier
))
NumBinopNode
.
generate_evaluation_code
(
self
,
code
)
def
calculate_result_code
(
self
):
if
self
.
operand1
.
type
.
is_float
or
self
.
operand2
.
type
.
is_float
:
return
"fmod(%s, %s)"
%
(
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
if
self
.
cdivision
:
if
self
.
type
.
is_float
:
return
"fmod%s(%s, %s)"
%
(
self
.
type
.
math_h_modifier
,
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
else
:
return
"(%s %% %s)"
%
(
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
else
:
return
"(%s %% %s)"
%
(
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
return
"__Pyx_mod_%s(%s, %s)"
%
(
self
.
type
.
specalization_name
(),
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
class
PowNode
(
NumBinopNode
):
# '**' operator.
...
...
@@ -4852,20 +4881,20 @@ class CascadedCmpNode(Node, CmpNode):
binop_node_classes
=
{
"or"
:
BoolBinopNode
,
"and"
:
BoolBinopNode
,
"or"
:
BoolBinopNode
,
"and"
:
BoolBinopNode
,
"|"
:
IntBinopNode
,
"^"
:
IntBinopNode
,
"&"
:
IntBinopNode
,
"<<"
:
IntBinopNode
,
">>"
:
IntBinopNode
,
"<<"
:
IntBinopNode
,
">>"
:
IntBinopNode
,
"+"
:
AddNode
,
"-"
:
SubNode
,
"*"
:
MulNode
,
"/"
:
NumBinop
Node
,
"//"
:
Floor
DivNode
,
"/"
:
Div
Node
,
"//"
:
DivNode
,
"%"
:
ModNode
,
"**"
:
PowNode
"**"
:
PowNode
}
def
binop_node
(
pos
,
operator
,
operand1
,
operand2
):
...
...
@@ -5639,3 +5668,34 @@ static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
return t;
}
"""
)
# ------------------------------ Division ------------------------------------
# This is so we can treat floating point and integer mod simultaneously.
mod_int_helper_macro
=
UtilityCode
(
proto
=
"""
#define fmod__Pyx_INT(a, b) ((a) % (b))
"""
)
mod_utility_code
=
UtilityCode
(
proto
=
"""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
"""
,
impl
=
"""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
%(type)s res = fmod%(math_h_modifier)s(a, b);
res += (res * b < 0) * b;
return res;
}
"""
)
div_utility_code
=
UtilityCode
(
proto
=
"""
static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
"""
,
impl
=
"""
static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
%(type)s res = a / b;
res -= (res < 0);
return res;
}
"""
)
Cython/Compiler/Options.py
View file @
a60c7801
...
...
@@ -55,22 +55,22 @@ c_line_in_traceback = 1
# Declare pragmas
option_types
=
{
'boundscheck'
:
bool
,
'nonecheck'
:
bool
,
'embedsignature'
:
bool
,
'locals'
:
dict
,
'auto_cpdef'
:
bool
,
}
option_defaults
=
{
'boundscheck'
:
True
,
'nonecheck'
:
False
,
'embedsignature'
:
False
,
'locals'
:
{},
'auto_cpdef'
:
False
,
'cdivision'
:
True
,
# Will be False in 0.12
}
# Override types possibilities above, if needed
option_types
=
{
}
for
key
,
val
in
option_defaults
.
items
():
if
key
not
in
option_types
:
option_types
[
key
]
=
type
(
val
)
def
parse_option_value
(
name
,
value
):
"""
Parses value as an option value for the given name and returns
...
...
tests/run/cdivision_CEP_516.pyx
View file @
a60c7801
...
...
@@ -18,6 +18,11 @@ True
[7.0, -7.0, -7.0, 7.0]
>>> [mod_double_c(a, b) for a, b in v]
[7.0, -7.0, -7.0, 7.0]
>>> [div_int_py(a, b) for a, b in v]
[1, -2, 1, -2]
>>> [div_int_c(a, b) for a, b in v]
[1, -1, 1, -1]
"""
cimport
cython
...
...
@@ -50,3 +55,12 @@ def mod_float_c(float a, float b):
def
mod_double_c
(
double
a
,
double
b
):
return
a
%
b
@
cython
.
cdivision
(
False
)
def
div_int_py
(
int
a
,
int
b
):
return
a
//
b
@
cython
.
cdivision
(
True
)
def
div_int_c
(
int
a
,
int
b
):
return
a
//
b
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