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
ae12787c
Commit
ae12787c
authored
Aug 11, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #821 from Daetalus/float_comparision
rewrite float comparison base on CPython implementation
parents
51b19ce0
76ec496e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
278 additions
and
127 deletions
+278
-127
src/runtime/float.cpp
src/runtime/float.cpp
+278
-127
No files found.
src/runtime/float.cpp
View file @
ae12787c
...
@@ -225,154 +225,306 @@ extern "C" Box* floatFloorDiv(BoxedFloat* lhs, Box* rhs) {
...
@@ -225,154 +225,306 @@ extern "C" Box* floatFloorDiv(BoxedFloat* lhs, Box* rhs) {
}
}
}
}
extern
"C"
Box
*
floatEqFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
/* Comparison is pretty much a nightmare. When comparing float to float,
assert
(
lhs
->
cls
==
float_cls
);
* we do it as straightforwardly (and long-windedly) as conceivable, so
assert
(
rhs
->
cls
==
float_cls
);
* that, e.g., Python x == y delivers the same result as the platform
return
boxBool
(
lhs
->
d
==
rhs
->
d
);
* C x == y when x and/or y is a NaN.
}
* When mixing float with an integer type, there's no good *uniform* approach.
* Converting the double to an integer obviously doesn't work, since we
* may lose info from fractional bits. Converting the integer to a double
* also has two failure modes: (1) a long int may trigger overflow (too
* large to fit in the dynamic range of a C double); (2) even a C long may have
* more bits than fit in a C double (e.g., on a a 64-bit box long may have
* 63 bits of precision, but a C double probably has only 53), and then
* we can falsely claim equality when low-order integer bits are lost by
* coercion to double. So this part is painful too.
*/
extern
"C"
Box
*
floatEqInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
static
PyObject
*
float_richcompare
(
PyObject
*
v
,
PyObject
*
w
,
int
op
)
noexcept
{
assert
(
lhs
->
cls
==
float_cls
);
double
i
,
j
;
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
int
r
=
0
;
return
boxBool
(
lhs
->
d
==
rhs
->
n
);
}
extern
"C"
Box
*
floatEq
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
PyFloat_Check
(
v
));
assert
(
lhs
->
cls
==
float_cls
);
i
=
PyFloat_AS_DOUBLE
(
v
);
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
return
floatEqInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
/* Switch on the type of w. Set i and j to doubles to be compared,
}
else
if
(
rhs
->
cls
==
float_cls
)
{
* and op to the richcomp to use.
return
floatEqFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
*/
}
else
if
(
rhs
->
cls
==
long_cls
)
{
if
(
PyFloat_Check
(
w
))
return
boxBool
(
lhs
->
d
==
PyLong_AsDouble
(
rhs
));
j
=
PyFloat_AS_DOUBLE
(
w
);
}
else
{
return
NotImplemented
;
else
if
(
!
std
::
isfinite
(
i
))
{
if
(
PyInt_Check
(
w
)
||
PyLong_Check
(
w
))
/* If i is an infinity, its magnitude exceeds any
* finite integer, so it doesn't matter which int we
* compare i with. If i is a NaN, similarly.
*/
j
=
0.0
;
else
goto
Unimplemented
;
}
}
}
extern
"C"
Box
*
floatNeFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
else
if
(
PyInt_Check
(
w
))
{
assert
(
lhs
->
cls
==
float_cls
);
long
jj
=
PyInt_AS_LONG
(
w
);
assert
(
rhs
->
cls
==
float_cls
);
/* In the worst realistic case I can imagine, C double is a
return
boxBool
(
lhs
->
d
!=
rhs
->
d
);
* Cray single with 48 bits of precision, and long has 64
}
* bits.
*/
#if SIZEOF_LONG > 6
unsigned
long
abs
=
(
unsigned
long
)(
jj
<
0
?
-
jj
:
jj
);
if
(
abs
>>
48
)
{
/* Needs more than 48 bits. Make it take the
* PyLong path.
*/
PyObject
*
result
;
PyObject
*
ww
=
PyLong_FromLong
(
jj
);
if
(
ww
==
NULL
)
return
NULL
;
result
=
float_richcompare
(
v
,
ww
,
op
);
Py_DECREF
(
ww
);
return
result
;
}
#endif
j
=
(
double
)
jj
;
assert
((
long
)
j
==
jj
);
}
extern
"C"
Box
*
floatNeInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
else
if
(
PyLong_Check
(
w
))
{
assert
(
lhs
->
cls
==
float_cls
);
int
vsign
=
i
==
0.0
?
0
:
i
<
0.0
?
-
1
:
1
;
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
int
wsign
=
_PyLong_Sign
(
w
);
return
boxBool
(
lhs
->
d
!=
rhs
->
n
);
size_t
nbits
;
}
int
exponent
;
if
(
vsign
!=
wsign
)
{
/* Magnitudes are irrelevant -- the signs alone
* determine the outcome.
*/
i
=
(
double
)
vsign
;
j
=
(
double
)
wsign
;
goto
Compare
;
}
/* The signs are the same. */
/* Convert w to a double if it fits. In particular, 0 fits. */
nbits
=
mpz_sizeinbase
(
static_cast
<
BoxedLong
*>
(
w
)
->
n
,
2
);
if
(
nbits
==
(
size_t
)
-
1
&&
PyErr_Occurred
())
{
/* This long is so large that size_t isn't big enough
* to hold the # of bits. Replace with little doubles
* that give the same outcome -- w is so large that
* its magnitude must exceed the magnitude of any
* finite float.
*/
PyErr_Clear
();
i
=
(
double
)
vsign
;
assert
(
wsign
!=
0
);
j
=
wsign
*
2.0
;
goto
Compare
;
}
if
(
nbits
<=
48
)
{
j
=
PyLong_AsDouble
(
w
);
/* It's impossible that <= 48 bits overflowed. */
assert
(
j
!=
-
1.0
||
!
PyErr_Occurred
());
goto
Compare
;
}
assert
(
wsign
!=
0
);
/* else nbits was 0 */
assert
(
vsign
!=
0
);
/* if vsign were 0, then since wsign is
* not 0, we would have taken the
* vsign != wsign branch at the start */
/* We want to work with non-negative numbers. */
if
(
vsign
<
0
)
{
/* "Multiply both sides" by -1; this also swaps the
* comparator.
*/
i
=
-
i
;
op
=
_Py_SwappedOp
[
op
];
}
assert
(
i
>
0.0
);
(
void
)
frexp
(
i
,
&
exponent
);
/* exponent is the # of bits in v before the radix point;
* we know that nbits (the # of bits in w) > 48 at this point
*/
if
(
exponent
<
0
||
(
size_t
)
exponent
<
nbits
)
{
i
=
1.0
;
j
=
2.0
;
goto
Compare
;
}
if
((
size_t
)
exponent
>
nbits
)
{
i
=
2.0
;
j
=
1.0
;
goto
Compare
;
}
/* v and w have the same number of bits before the radix
* point. Construct two longs that have the same comparison
* outcome.
*/
{
double
fracpart
;
double
intpart
;
PyObject
*
result
=
NULL
;
PyObject
*
one
=
NULL
;
PyObject
*
vv
=
NULL
;
PyObject
*
ww
=
w
;
if
(
wsign
<
0
)
{
ww
=
PyNumber_Negative
(
w
);
if
(
ww
==
NULL
)
goto
Error
;
}
else
Py_INCREF
(
ww
);
fracpart
=
modf
(
i
,
&
intpart
);
vv
=
PyLong_FromDouble
(
intpart
);
if
(
vv
==
NULL
)
goto
Error
;
if
(
fracpart
!=
0.0
)
{
/* Shift left, and or a 1 bit into vv
* to represent the lost fraction.
*/
PyObject
*
temp
;
one
=
PyInt_FromLong
(
1
);
if
(
one
==
NULL
)
goto
Error
;
temp
=
PyNumber_Lshift
(
ww
,
one
);
if
(
temp
==
NULL
)
goto
Error
;
Py_DECREF
(
ww
);
ww
=
temp
;
temp
=
PyNumber_Lshift
(
vv
,
one
);
if
(
temp
==
NULL
)
goto
Error
;
Py_DECREF
(
vv
);
vv
=
temp
;
temp
=
PyNumber_Or
(
vv
,
one
);
if
(
temp
==
NULL
)
goto
Error
;
Py_DECREF
(
vv
);
vv
=
temp
;
}
extern
"C"
Box
*
floatNe
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
r
=
PyObject_RichCompareBool
(
vv
,
ww
,
op
);
assert
(
lhs
->
cls
==
float_cls
);
if
(
r
<
0
)
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
goto
Error
;
return
floatNeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
result
=
PyBool_FromLong
(
r
);
}
else
if
(
rhs
->
cls
==
float_cls
)
{
Error:
return
floatNeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Py_XDECREF
(
vv
);
}
else
if
(
rhs
->
cls
==
long_cls
)
{
Py_XDECREF
(
ww
);
return
boxBool
(
lhs
->
d
!=
PyLong_AsDouble
(
rhs
));
Py_XDECREF
(
one
);
}
else
{
return
result
;
return
NotImplemented
;
}
}
}
/* else if (PyLong_Check(w)) */
}
extern
"C"
Box
*
floatLtFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
else
/* w isn't float, int, or long */
assert
(
lhs
->
cls
==
float_cls
);
goto
Unimplemented
;
assert
(
rhs
->
cls
==
float_cls
);
return
boxBool
(
lhs
->
d
<
rhs
->
d
);
}
extern
"C"
Box
*
floatLtInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
Compare:
assert
(
lhs
->
cls
==
float_cls
);
PyFPE_START_PROTECT
(
"richcompare"
,
return
NULL
)
switch
(
op
)
{
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
case
Py_EQ
:
return
boxBool
(
lhs
->
d
<
rhs
->
n
);
r
=
i
==
j
;
break
;
case
Py_NE
:
r
=
i
!=
j
;
break
;
case
Py_LE
:
r
=
i
<=
j
;
break
;
case
Py_GE
:
r
=
i
>=
j
;
break
;
case
Py_LT
:
r
=
i
<
j
;
break
;
case
Py_GT
:
r
=
i
>
j
;
break
;
}
PyFPE_END_PROTECT
(
r
)
return
PyBool_FromLong
(
r
);
Unimplemented:
Py_INCREF
(
Py_NotImplemented
);
return
Py_NotImplemented
;
}
}
extern
"C"
Box
*
floatLt
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
floatEq
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
!
isSubclass
(
lhs
->
cls
,
float_cls
))
{
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__eq__' requires a 'float' object but received a '%s'"
,
return
floatLtInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
return
floatLtFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
res
=
float_richcompare
(
lhs
,
rhs
,
Py_EQ
);
}
else
if
(
rhs
->
cls
==
long_cls
)
{
if
(
!
res
)
{
return
boxBool
(
lhs
->
d
<
PyLong_AsDouble
(
rhs
));
throwCAPIException
();
}
else
{
return
NotImplemented
;
}
}
}
extern
"C"
Box
*
floatLeFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
return
res
;
assert
(
lhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
return
boxBool
(
lhs
->
d
<=
rhs
->
d
);
}
}
extern
"C"
Box
*
floatLeInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
extern
"C"
Box
*
floatNe
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
!
isSubclass
(
lhs
->
cls
,
float_cls
))
{
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
raiseExcHelper
(
TypeError
,
"descriptor '__ne__' requires a 'float' object but received a '%s'"
,
return
boxBool
(
lhs
->
d
<=
rhs
->
n
);
getTypeName
(
lhs
));
}
Box
*
res
=
float_richcompare
(
lhs
,
rhs
,
Py_NE
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
}
extern
"C"
Box
*
floatLe
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
floatLe
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
!
isSubclass
(
lhs
->
cls
,
float_cls
))
{
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__le__' requires a 'float' object but received a '%s'"
,
return
floatLeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
return
floatLeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
res
=
float_richcompare
(
lhs
,
rhs
,
Py_LE
);
}
else
if
(
rhs
->
cls
==
long_cls
)
{
if
(
!
res
)
{
return
boxBool
(
lhs
->
d
<=
PyLong_AsDouble
(
rhs
));
throwCAPIException
();
}
else
{
return
NotImplemented
;
}
}
}
extern
"C"
Box
*
floatGtFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
return
boxBool
(
lhs
->
d
>
rhs
->
d
);
}
extern
"C"
Box
*
floatGtInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
return
res
;
assert
(
lhs
->
cls
==
float_cls
);
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
return
boxBool
(
lhs
->
d
>
rhs
->
n
);
}
}
extern
"C"
Box
*
floatGt
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
floatLt
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
!
isSubclass
(
lhs
->
cls
,
float_cls
))
{
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__lt__' requires a 'float' object but received a '%s'"
,
return
floatGtInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
return
floatGtFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
res
=
float_richcompare
(
lhs
,
rhs
,
Py_LT
);
}
else
if
(
rhs
->
cls
==
long_cls
)
{
if
(
!
res
)
{
return
boxBool
(
lhs
->
d
>
PyLong_AsDouble
(
rhs
));
throwCAPIException
();
}
else
{
return
NotImplemented
;
}
}
}
extern
"C"
Box
*
floatGeFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
return
res
;
assert
(
lhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
return
boxBool
(
lhs
->
d
>=
rhs
->
d
);
}
}
extern
"C"
Box
*
floatGeInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
extern
"C"
Box
*
floatGe
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
!
isSubclass
(
lhs
->
cls
,
float_cls
))
{
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
raiseExcHelper
(
TypeError
,
"descriptor '__ge__' requires a 'float' object but received a '%s'"
,
return
boxBool
(
lhs
->
d
>=
rhs
->
n
);
getTypeName
(
lhs
));
}
Box
*
res
=
float_richcompare
(
lhs
,
rhs
,
Py_GE
);
if
(
!
res
)
{
throwCAPIException
();
}
return
res
;
}
}
extern
"C"
Box
*
floatGe
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
floatGt
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
!
isSubclass
(
lhs
->
cls
,
float_cls
))
{
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
raiseExcHelper
(
TypeError
,
"descriptor '__gt__' requires a 'float' object but received a '%s'"
,
return
floatGeInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
getTypeName
(
lhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
return
floatGeFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
Box
*
res
=
float_richcompare
(
lhs
,
rhs
,
Py_GT
);
}
else
if
(
rhs
->
cls
==
long_cls
)
{
if
(
!
res
)
{
return
boxBool
(
lhs
->
d
>=
PyLong_AsDouble
(
rhs
));
throwCAPIException
();
}
else
{
return
NotImplemented
;
}
}
return
res
;
}
}
extern
"C"
Box
*
floatModFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
extern
"C"
Box
*
floatModFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
...
@@ -1498,13 +1650,6 @@ void setupFloat() {
...
@@ -1498,13 +1650,6 @@ void setupFloat() {
_addFunc
(
"__floordiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatFloorDivFloat
,
(
void
*
)
floatFloorDivInt
,
(
void
*
)
floatFloorDiv
);
_addFunc
(
"__floordiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatFloorDivFloat
,
(
void
*
)
floatFloorDivInt
,
(
void
*
)
floatFloorDiv
);
_addFunc
(
"__truediv__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatTruediv
);
_addFunc
(
"__truediv__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatTruediv
);
_addFunc
(
"__eq__"
,
BOXED_BOOL
,
(
void
*
)
floatEqFloat
,
(
void
*
)
floatEqInt
,
(
void
*
)
floatEq
);
_addFunc
(
"__ge__"
,
BOXED_BOOL
,
(
void
*
)
floatGeFloat
,
(
void
*
)
floatGeInt
,
(
void
*
)
floatGe
);
_addFunc
(
"__gt__"
,
BOXED_BOOL
,
(
void
*
)
floatGtFloat
,
(
void
*
)
floatGtInt
,
(
void
*
)
floatGt
);
_addFunc
(
"__le__"
,
BOXED_BOOL
,
(
void
*
)
floatLeFloat
,
(
void
*
)
floatLeInt
,
(
void
*
)
floatLe
);
_addFunc
(
"__lt__"
,
BOXED_BOOL
,
(
void
*
)
floatLtFloat
,
(
void
*
)
floatLtInt
,
(
void
*
)
floatLt
);
_addFunc
(
"__ne__"
,
BOXED_BOOL
,
(
void
*
)
floatNeFloat
,
(
void
*
)
floatNeInt
,
(
void
*
)
floatNe
);
_addFunc
(
"__mod__"
,
BOXED_FLOAT
,
(
void
*
)
floatModFloat
,
(
void
*
)
floatModInt
,
(
void
*
)
floatMod
);
_addFunc
(
"__mod__"
,
BOXED_FLOAT
,
(
void
*
)
floatModFloat
,
(
void
*
)
floatModInt
,
(
void
*
)
floatMod
);
_addFunc
(
"__rmod__"
,
BOXED_FLOAT
,
(
void
*
)
floatRModFloat
,
(
void
*
)
floatRModInt
,
(
void
*
)
floatRMod
);
_addFunc
(
"__rmod__"
,
BOXED_FLOAT
,
(
void
*
)
floatRModFloat
,
(
void
*
)
floatRModInt
,
(
void
*
)
floatRMod
);
_addFunc
(
"__mul__"
,
BOXED_FLOAT
,
(
void
*
)
floatMulFloat
,
(
void
*
)
floatMulInt
,
(
void
*
)
floatMul
);
_addFunc
(
"__mul__"
,
BOXED_FLOAT
,
(
void
*
)
floatMulFloat
,
(
void
*
)
floatMulInt
,
(
void
*
)
floatMul
);
...
@@ -1518,6 +1663,12 @@ void setupFloat() {
...
@@ -1518,6 +1663,12 @@ void setupFloat() {
addRTFunction
(
float_new
,
(
void
*
)
floatNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
addRTFunction
(
float_new
,
(
void
*
)
floatNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
float_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
float_new
,
{
boxFloat
(
0.0
)
}));
float_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
float_new
,
{
boxFloat
(
0.0
)
}));
float_cls
->
giveAttr
(
"__eq__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatEq
,
UNKNOWN
,
2
)));
float_cls
->
giveAttr
(
"__ne__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatNe
,
UNKNOWN
,
2
)));
float_cls
->
giveAttr
(
"__le__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatLe
,
UNKNOWN
,
2
)));
float_cls
->
giveAttr
(
"__lt__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatLt
,
UNKNOWN
,
2
)));
float_cls
->
giveAttr
(
"__ge__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatGe
,
UNKNOWN
,
2
)));
float_cls
->
giveAttr
(
"__gt__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatGt
,
UNKNOWN
,
2
)));
float_cls
->
giveAttr
(
"__neg__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatNeg
,
BOXED_FLOAT
,
1
)));
float_cls
->
giveAttr
(
"__neg__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatNeg
,
BOXED_FLOAT
,
1
)));
float_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatPos
,
BOXED_FLOAT
,
1
)));
float_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatPos
,
BOXED_FLOAT
,
1
)));
...
...
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