Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
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
Boxiang Sun
Pyston
Commits
b569aed6
Commit
b569aed6
authored
Apr 22, 2015
by
Travis Hance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement pow_float_float without boxing
parent
e7c1bf94
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
69 additions
and
26 deletions
+69
-26
from_cpython/Objects/floatobject.c
from_cpython/Objects/floatobject.c
+52
-24
src/runtime/float.cpp
src/runtime/float.cpp
+8
-2
test/tests/float.py
test/tests/float.py
+9
-0
No files found.
from_cpython/Objects/floatobject.c
View file @
b569aed6
...
...
@@ -820,12 +820,14 @@ float_floor_div(PyObject *v, PyObject *w)
x is not an infinity or nan. */
#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0)
// pyston change: make not static
inline
int
float_pow_unboxed
(
double
iv
,
double
iw
,
double
*
res
);
// pyston change: split this up into float_pow and and float_pow_unboxed
PyObject
*
float_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
{
double
iv
,
iw
,
ix
;
int
negate_result
=
0
;
double
iv
,
iw
,
res
;
int
err
;
if
((
PyObject
*
)
z
!=
Py_None
)
{
PyErr_SetString
(
PyExc_TypeError
,
"pow() 3rd argument not "
...
...
@@ -836,15 +838,32 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
CONVERT_TO_DOUBLE
(
v
,
iv
);
CONVERT_TO_DOUBLE
(
w
,
iw
);
err
=
float_pow_unboxed
(
iv
,
iw
,
&
res
);
if
(
err
)
{
return
NULL
;
}
else
{
return
PyFloat_FromDouble
(
res
);
}
}
int
float_pow_unboxed
(
double
iv
,
double
iw
,
double
*
res
)
{
double
ix
;
int
negate_result
=
0
;
/* Sort out special cases here instead of relying on pow() */
if
(
iw
==
0
)
{
/* v**0 is 1, even 0**0 */
return
PyFloat_FromDouble
(
1
.
0
);
*
res
=
1
.
0
;
return
0
;
}
if
(
Py_IS_NAN
(
iv
))
{
/* nan**w = nan, unless w == 0 */
return
PyFloat_FromDouble
(
iv
);
*
res
=
iv
;
return
0
;
}
if
(
Py_IS_NAN
(
iw
))
{
/* v**nan = nan, unless v == 1; 1**nan = 1 */
return
PyFloat_FromDouble
(
iv
==
1
.
0
?
1
.
0
:
iw
);
*
res
=
(
iv
==
1
.
0
?
1
.
0
:
iw
);
return
0
;
}
if
(
Py_IS_INFINITY
(
iw
))
{
/* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if
...
...
@@ -854,12 +873,16 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
* abs(v) > 1 (including case where v infinite)
*/
iv
=
fabs
(
iv
);
if
(
iv
==
1
.
0
)
return
PyFloat_FromDouble
(
1
.
0
);
else
if
((
iw
>
0
.
0
)
==
(
iv
>
1
.
0
))
return
PyFloat_FromDouble
(
fabs
(
iw
));
/* return inf */
else
return
PyFloat_FromDouble
(
0
.
0
);
if
(
iv
==
1
.
0
)
{
*
res
=
1
.
0
;
return
0
;
}
else
if
((
iw
>
0
.
0
)
==
(
iv
>
1
.
0
))
{
*
res
=
fabs
(
iw
);
return
0
;
}
else
{
*
res
=
0
.
0
;
return
0
;
}
}
if
(
Py_IS_INFINITY
(
iv
))
{
/* (+-inf)**w is: inf for w positive, 0 for w negative; in
...
...
@@ -867,11 +890,13 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
* an odd integer.
*/
int
iw_is_odd
=
DOUBLE_IS_ODD_INTEGER
(
iw
);
if
(
iw
>
0
.
0
)
return
PyFloat_FromDouble
(
iw_is_odd
?
iv
:
fabs
(
iv
));
else
return
PyFloat_FromDouble
(
iw_is_odd
?
copysign
(
0
.
0
,
iv
)
:
0
.
0
);
if
(
iw
>
0
.
0
)
{
*
res
=
(
iw_is_odd
?
iv
:
fabs
(
iv
));
return
0
;
}
else
{
*
res
=
(
iw_is_odd
?
copysign
(
0
.
0
,
iv
)
:
0
.
0
);
return
0
;
}
}
if
(
iv
==
0
.
0
)
{
/* 0**w is: 0 for w positive, 1 for w zero
(already dealt with above), and an error
...
...
@@ -881,10 +906,11 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"0.0 cannot be raised to a "
"negative power"
);
return
NULL
;
return
1
;
}
/* use correct sign if iw is odd */
return
PyFloat_FromDouble
(
iw_is_odd
?
iv
:
0
.
0
);
*
res
=
(
iw_is_odd
?
iv
:
0
.
0
);
return
0
;
}
if
(
iv
<
0
.
0
)
{
...
...
@@ -894,7 +920,7 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
if
(
iw
!=
floor
(
iw
))
{
PyErr_SetString
(
PyExc_ValueError
,
"negative number "
"cannot be raised to a fractional power"
);
return
NULL
;
return
1
;
}
/* iw is an exact integer, albeit perhaps a very large
* one. Replace iv by its absolute value and remember
...
...
@@ -916,7 +942,8 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
* happen to be representable in a *C* integer. That's a
* bug.
*/
return
PyFloat_FromDouble
(
negate_result
?
-
1
.
0
:
1
.
0
);
*
res
=
(
negate_result
?
-
1
.
0
:
1
.
0
);
return
0
;
}
/* Now iv and iw are finite, iw is nonzero, and iv is
...
...
@@ -924,7 +951,7 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
* the platform pow to step in and do the rest.
*/
errno
=
0
;
PyFPE_START_PROTECT
(
"pow"
,
return
NULL
)
PyFPE_START_PROTECT
(
"pow"
,
return
1
)
ix
=
pow
(
iv
,
iw
);
PyFPE_END_PROTECT
(
ix
)
Py_ADJUST_ERANGE1
(
ix
);
...
...
@@ -937,9 +964,10 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
*/
PyErr_SetFromErrno
(
errno
==
ERANGE
?
PyExc_OverflowError
:
PyExc_ValueError
);
return
NULL
;
return
1
;
}
return
PyFloat_FromDouble
(
ix
);
*
res
=
ix
;
return
0
;
}
#undef DOUBLE_IS_ODD_INTEGER
...
...
src/runtime/float.cpp
View file @
b569aed6
...
...
@@ -31,6 +31,7 @@ extern "C" PyObject* float_as_integer_ratio(PyObject* v, PyObject* unused) noexc
extern
"C"
PyObject
*
float_is_integer
(
PyObject
*
v
)
noexcept
;
extern
"C"
PyObject
*
float__format__
(
PyObject
*
v
)
noexcept
;
extern
"C"
PyObject
*
float_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
noexcept
;
extern
"C"
int
float_pow_unboxed
(
double
iv
,
double
iw
,
double
*
res
)
noexcept
;
namespace
pyston
{
...
...
@@ -446,8 +447,13 @@ extern "C" Box* floatPowInt(BoxedFloat* lhs, BoxedInt* rhs, Box* mod = None) {
}
extern
"C"
double
pow_float_float
(
double
lhs
,
double
rhs
)
{
// TODO inline this without the boxing
return
unboxFloat
(
floatPowFloat
(
static_cast
<
BoxedFloat
*>
(
boxFloat
(
lhs
)),
static_cast
<
BoxedFloat
*>
(
boxFloat
(
rhs
))));
double
res
;
int
err
=
float_pow_unboxed
(
lhs
,
rhs
,
&
res
);
if
(
err
)
{
throwCAPIException
();
}
else
{
return
res
;
}
}
extern
"C"
Box
*
floatMulFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
...
...
test/tests/float.py
View file @
b569aed6
...
...
@@ -65,3 +65,12 @@ print (0.5).as_integer_ratio()
print
(
0.5
).
is_integer
()
print
(
1.0
).
is_integer
()
print
1.0
.
__hash__
(),
1.1
.
__hash__
(),
-
1.1
.
__hash__
()
print
1.0
**
(
10
**
100
)
print
(
-
1.0
)
**
(
10
**
100
)
print
(
-
1.0
)
**
(
10
**
100
+
1
)
print
0.0
**
0.0
try
:
0.0
**
(
-
1.0
)
except
ZeroDivisionError
as
e
:
print
e
.
message
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