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
c36b3f72
Commit
c36b3f72
authored
Jan 04, 2001
by
Neil Schemenauer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make float a new style number type.
parent
5856158f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
108 additions
and
42 deletions
+108
-42
Objects/floatobject.c
Objects/floatobject.c
+108
-42
No files found.
Objects/floatobject.c
View file @
c36b3f72
...
@@ -256,6 +256,38 @@ PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
...
@@ -256,6 +256,38 @@ PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
}
}
}
}
/* Macro and helper that convert PyObject obj to a C double and store
the value in dbl; this replaces the functionality of the coercion
slot function */
#define CONVERT_TO_DOUBLE(obj, dbl) \
if (PyFloat_Check(obj)) \
dbl = PyFloat_AS_DOUBLE(obj); \
else if (convert_to_double(&(obj), &(dbl)) < 0) \
return obj;
static
int
convert_to_double
(
PyObject
**
v
,
double
*
dbl
)
{
register
PyObject
*
obj
=
*
v
;
if
(
PyInt_Check
(
obj
))
{
*
dbl
=
(
double
)
PyInt_AS_LONG
(
obj
);
}
else
if
(
PyLong_Check
(
obj
))
{
PyFPE_START_PROTECT
(
"convert_to_double"
,
{
*
v
=
NULL
;
return
-
1
;})
*
dbl
=
PyLong_AsDouble
(
obj
);
PyFPE_END_PROTECT
(
result
)
}
else
{
Py_INCREF
(
Py_NotImplemented
);
*
v
=
Py_NotImplemented
;
return
-
1
;
}
return
0
;
}
/* Precisions used by repr() and str(), respectively.
/* Precisions used by repr() and str(), respectively.
The repr() precision (17 significant decimal digits) is the minimal number
The repr() precision (17 significant decimal digits) is the minimal number
...
@@ -314,6 +346,15 @@ float_compare(PyFloatObject *v, PyFloatObject *w)
...
@@ -314,6 +346,15 @@ float_compare(PyFloatObject *v, PyFloatObject *w)
return
(
i
<
j
)
?
-
1
:
(
i
>
j
)
?
1
:
0
;
return
(
i
<
j
)
?
-
1
:
(
i
>
j
)
?
1
:
0
;
}
}
/* Needed for the new style number compare slots */
static
PyObject
*
float_cmp
(
PyObject
*
v
,
PyObject
*
w
)
{
double
a
,
b
;
CONVERT_TO_DOUBLE
(
v
,
a
);
CONVERT_TO_DOUBLE
(
w
,
b
);
return
PyInt_FromLong
((
a
<
b
)
?
-
1
:
(
a
>
b
)
?
1
:
0
);
}
static
long
static
long
float_hash
(
PyFloatObject
*
v
)
float_hash
(
PyFloatObject
*
v
)
...
@@ -322,62 +363,69 @@ float_hash(PyFloatObject *v)
...
@@ -322,62 +363,69 @@ float_hash(PyFloatObject *v)
}
}
static
PyObject
*
static
PyObject
*
float_add
(
Py
FloatObject
*
v
,
PyFloat
Object
*
w
)
float_add
(
Py
Object
*
v
,
Py
Object
*
w
)
{
{
double
result
;
double
a
,
b
;
CONVERT_TO_DOUBLE
(
v
,
a
);
CONVERT_TO_DOUBLE
(
w
,
b
);
PyFPE_START_PROTECT
(
"add"
,
return
0
)
PyFPE_START_PROTECT
(
"add"
,
return
0
)
result
=
v
->
ob_fval
+
w
->
ob_fval
;
a
=
a
+
b
;
PyFPE_END_PROTECT
(
result
)
PyFPE_END_PROTECT
(
a
)
return
PyFloat_FromDouble
(
result
);
return
PyFloat_FromDouble
(
a
);
}
}
static
PyObject
*
static
PyObject
*
float_sub
(
Py
FloatObject
*
v
,
PyFloat
Object
*
w
)
float_sub
(
Py
Object
*
v
,
Py
Object
*
w
)
{
{
double
result
;
double
a
,
b
;
CONVERT_TO_DOUBLE
(
v
,
a
);
CONVERT_TO_DOUBLE
(
w
,
b
);
PyFPE_START_PROTECT
(
"subtract"
,
return
0
)
PyFPE_START_PROTECT
(
"subtract"
,
return
0
)
result
=
v
->
ob_fval
-
w
->
ob_fval
;
a
=
a
-
b
;
PyFPE_END_PROTECT
(
result
)
PyFPE_END_PROTECT
(
a
)
return
PyFloat_FromDouble
(
result
);
return
PyFloat_FromDouble
(
a
);
}
}
static
PyObject
*
static
PyObject
*
float_mul
(
Py
FloatObject
*
v
,
PyFloat
Object
*
w
)
float_mul
(
Py
Object
*
v
,
Py
Object
*
w
)
{
{
double
result
;
double
a
,
b
;
CONVERT_TO_DOUBLE
(
v
,
a
);
CONVERT_TO_DOUBLE
(
w
,
b
);
PyFPE_START_PROTECT
(
"multiply"
,
return
0
)
PyFPE_START_PROTECT
(
"multiply"
,
return
0
)
result
=
v
->
ob_fval
*
w
->
ob_fval
;
a
=
a
*
b
;
PyFPE_END_PROTECT
(
result
)
PyFPE_END_PROTECT
(
a
)
return
PyFloat_FromDouble
(
result
);
return
PyFloat_FromDouble
(
a
);
}
}
static
PyObject
*
static
PyObject
*
float_div
(
Py
FloatObject
*
v
,
PyFloat
Object
*
w
)
float_div
(
Py
Object
*
v
,
Py
Object
*
w
)
{
{
double
result
;
double
a
,
b
;
if
(
w
->
ob_fval
==
0
)
{
CONVERT_TO_DOUBLE
(
v
,
a
);
CONVERT_TO_DOUBLE
(
w
,
b
);
if
(
b
==
0
.
0
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"float division"
);
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"float division"
);
return
NULL
;
return
NULL
;
}
}
PyFPE_START_PROTECT
(
"divide"
,
return
0
)
PyFPE_START_PROTECT
(
"divide"
,
return
0
)
result
=
v
->
ob_fval
/
w
->
ob_fval
;
a
=
a
/
b
;
PyFPE_END_PROTECT
(
result
)
PyFPE_END_PROTECT
(
a
)
return
PyFloat_FromDouble
(
result
);
return
PyFloat_FromDouble
(
a
);
}
}
static
PyObject
*
static
PyObject
*
float_rem
(
Py
FloatObject
*
v
,
PyFloat
Object
*
w
)
float_rem
(
Py
Object
*
v
,
Py
Object
*
w
)
{
{
double
vx
,
wx
;
double
vx
,
wx
;
double
mod
;
double
mod
;
wx
=
w
->
ob_fval
;
CONVERT_TO_DOUBLE
(
v
,
vx
);
CONVERT_TO_DOUBLE
(
w
,
wx
);
if
(
wx
==
0
.
0
)
{
if
(
wx
==
0
.
0
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"float modulo"
);
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"float modulo"
);
return
NULL
;
return
NULL
;
}
}
PyFPE_START_PROTECT
(
"modulo"
,
return
0
)
PyFPE_START_PROTECT
(
"modulo"
,
return
0
)
vx
=
v
->
ob_fval
;
mod
=
fmod
(
vx
,
wx
);
mod
=
fmod
(
vx
,
wx
);
/* note: checking mod*wx < 0 is incorrect -- underflows to
/* note: checking mod*wx < 0 is incorrect -- underflows to
0 if wx < sqrt(smallest nonzero double) */
0 if wx < sqrt(smallest nonzero double) */
...
@@ -389,17 +437,17 @@ float_rem(PyFloatObject *v, PyFloatObject *w)
...
@@ -389,17 +437,17 @@ float_rem(PyFloatObject *v, PyFloatObject *w)
}
}
static
PyObject
*
static
PyObject
*
float_divmod
(
Py
FloatObject
*
v
,
PyFloat
Object
*
w
)
float_divmod
(
Py
Object
*
v
,
Py
Object
*
w
)
{
{
double
vx
,
wx
;
double
vx
,
wx
;
double
div
,
mod
,
floordiv
;
double
div
,
mod
,
floordiv
;
wx
=
w
->
ob_fval
;
CONVERT_TO_DOUBLE
(
v
,
vx
);
CONVERT_TO_DOUBLE
(
w
,
wx
);
if
(
wx
==
0
.
0
)
{
if
(
wx
==
0
.
0
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"float divmod()"
);
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"float divmod()"
);
return
NULL
;
return
NULL
;
}
}
PyFPE_START_PROTECT
(
"divmod"
,
return
0
)
PyFPE_START_PROTECT
(
"divmod"
,
return
0
)
vx
=
v
->
ob_fval
;
mod
=
fmod
(
vx
,
wx
);
mod
=
fmod
(
vx
,
wx
);
/* fmod is typically exact, so vx-mod is *mathematically* an
/* fmod is typically exact, so vx-mod is *mathematically* an
exact multiple of wx. But this is fp arithmetic, and fp
exact multiple of wx. But this is fp arithmetic, and fp
...
@@ -437,7 +485,7 @@ static double powu(double x, long n)
...
@@ -437,7 +485,7 @@ static double powu(double x, long n)
}
}
static
PyObject
*
static
PyObject
*
float_pow
(
Py
FloatObject
*
v
,
PyObject
*
w
,
PyFloat
Object
*
z
)
float_pow
(
Py
Object
*
v
,
PyObject
*
w
,
Py
Object
*
z
)
{
{
double
iv
,
iw
,
ix
;
double
iv
,
iw
,
ix
;
long
intw
;
long
intw
;
...
@@ -446,17 +494,18 @@ float_pow(PyFloatObject *v, PyObject *w, PyFloatObject *z)
...
@@ -446,17 +494,18 @@ float_pow(PyFloatObject *v, PyObject *w, PyFloatObject *z)
* long integers. Maybe something clever with logarithms could be done.
* long integers. Maybe something clever with logarithms could be done.
* [AMK]
* [AMK]
*/
*/
iv
=
v
->
ob_fval
;
CONVERT_TO_DOUBLE
(
v
,
iv
)
;
iw
=
((
PyFloatObject
*
)
w
)
->
ob_fval
;
CONVERT_TO_DOUBLE
(
w
,
iw
)
;
intw
=
(
long
)
iw
;
intw
=
(
long
)
iw
;
/* Sort out special cases here instead of relying on pow() */
/* Sort out special cases here instead of relying on pow() */
if
(
iw
==
0
)
{
/* x**0 is 1, even 0**0 */
if
(
iw
==
0
)
{
/* x**0 is 1, even 0**0 */
PyFPE_START_PROTECT
(
"pow"
,
return
NULL
)
PyFPE_START_PROTECT
(
"pow"
,
return
NULL
)
if
((
PyObject
*
)
z
!=
Py_None
)
{
if
((
PyObject
*
)
z
!=
Py_None
)
{
ix
=
fmod
(
1
.
0
,
z
->
ob_fval
);
double
iz
;
if
(
ix
!=
0
&&
z
->
ob_fval
<
0
)
CONVERT_TO_DOUBLE
(
w
,
iz
);
ix
+=
z
->
ob_fval
;
ix
=
fmod
(
1
.
0
,
iz
);
if
(
ix
!=
0
&&
iz
<
0
)
ix
+=
iz
;
}
}
else
else
ix
=
1
.
0
;
ix
=
1
.
0
;
...
@@ -501,15 +550,14 @@ float_pow(PyFloatObject *v, PyObject *w, PyFloatObject *z)
...
@@ -501,15 +550,14 @@ float_pow(PyFloatObject *v, PyObject *w, PyFloatObject *z)
return
NULL
;
return
NULL
;
}
}
if
((
PyObject
*
)
z
!=
Py_None
)
{
if
((
PyObject
*
)
z
!=
Py_None
)
{
PyFPE_START_PROTECT
(
"pow"
,
return
NULL
)
double
iz
;
ix
=
fmod
(
ix
,
z
->
ob_fval
);
/* XXX To Be Rewritten */
CONVERT_TO_DOUBLE
(
z
,
iz
);
if
(
ix
!=
0
&&
PyFPE_START_PROTECT
(
"pow"
,
return
0
)
((
iv
<
0
&&
z
->
ob_fval
>
0
)
||
ix
=
fmod
(
ix
,
iz
);
/* XXX To Be Rewritten */
(
iv
>
0
&&
z
->
ob_fval
<
0
)
if
(
ix
!=
0
&&
((
iv
<
0
&&
iz
>
0
)
||
(
iv
>
0
&&
iz
<
0
)
))
{
))
{
ix
+=
iz
;
ix
+=
z
->
ob_fval
;
}
}
PyFPE_END_PROTECT
(
ix
)
PyFPE_END_PROTECT
(
ix
)
}
}
return
PyFloat_FromDouble
(
ix
);
return
PyFloat_FromDouble
(
ix
);
}
}
...
@@ -611,6 +659,20 @@ static PyNumberMethods float_as_number = {
...
@@ -611,6 +659,20 @@ static PyNumberMethods float_as_number = {
(
unaryfunc
)
float_float
,
/*nb_float*/
(
unaryfunc
)
float_float
,
/*nb_float*/
0
,
/*nb_oct*/
0
,
/*nb_oct*/
0
,
/*nb_hex*/
0
,
/*nb_hex*/
0
,
/*nb_inplace_add*/
0
,
/*nb_inplace_subtract*/
0
,
/*nb_inplace_multiply*/
0
,
/*nb_inplace_divide*/
0
,
/*nb_inplace_remainder*/
0
,
/*nb_inplace_power*/
0
,
/*nb_inplace_lshift*/
0
,
/*nb_inplace_rshift*/
0
,
/*nb_inplace_and*/
0
,
/*nb_inplace_xor*/
0
,
/*nb_inplace_or*/
/* New style slots: */
(
binaryfunc
)
float_cmp
,
/*nb_cmp*/
};
};
PyTypeObject
PyFloat_Type
=
{
PyTypeObject
PyFloat_Type
=
{
...
@@ -631,6 +693,10 @@ PyTypeObject PyFloat_Type = {
...
@@ -631,6 +693,10 @@ PyTypeObject PyFloat_Type = {
(
hashfunc
)
float_hash
,
/*tp_hash*/
(
hashfunc
)
float_hash
,
/*tp_hash*/
0
,
/*tp_call*/
0
,
/*tp_call*/
(
reprfunc
)
float_str
,
/*tp_str*/
(
reprfunc
)
float_str
,
/*tp_str*/
0
,
/*tp_getattro*/
0
,
/*tp_setattro*/
0
,
/*tp_as_buffer*/
Py_TPFLAGS_NEWSTYLENUMBER
/*tp_flags*/
};
};
void
void
...
...
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