Commit fb499bc7 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #543 from tjhance/floathex

implement float.hex and float.fromhex
parents 56f2d23f d7ee74e9
......@@ -377,6 +377,7 @@ STDOBJECT_SRCS := \
capsule.c \
stringobject.c \
exceptions.c \
floatobject.c \
unicodeobject.c \
unicodectype.c \
bytearrayobject.c \
......
......@@ -79,6 +79,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
capsule.c
cobject.c
exceptions.c
floatobject.c
iterobject.c
memoryobject.c
stringobject.c
......
......@@ -12,16 +12,10 @@ PyFloatObject represents a (double precision) floating point number.
extern "C" {
#endif
// Pyston change: this is not the format we're using
// - actually I think it is but there's no reason to have multiple definitions.
#if 0
typedef struct {
PyObject_HEAD
double ob_fval;
} PyFloatObject;
#endif
struct _PyFloatObject;
typedef struct _PyFloatObject PyFloatObject;
// Pyston change: this is no longer a static object
PyAPI_DATA(PyTypeObject*) float_cls;
......
......@@ -424,3 +424,37 @@ typedef PY_LONG_LONG Py_intptr_t;
#endif /* Py_PYPORT_H */
/* Py_ADJUST_ERANGE1(x)
* Py_ADJUST_ERANGE2(x, y)
* Set errno to 0 before calling a libm function, and invoke one of these
* macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful
* for functions returning complex results). This makes two kinds of
* adjustments to errno: (A) If it looks like the platform libm set
* errno=ERANGE due to underflow, clear errno. (B) If it looks like the
* platform libm overflowed but didn't set errno, force errno to ERANGE. In
* effect, we're trying to force a useful implementation of C89 errno
* behavior.
* Caution:
* This isn't reliable. See Py_OVERFLOWED comments.
* X and Y may be evaluated more than once.
*/
#define Py_ADJUST_ERANGE1(X) \
do { \
if (errno == 0) { \
if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
errno = ERANGE; \
} \
else if (errno == ERANGE && (X) == 0.0) \
errno = 0; \
} while(0)
#define Py_ADJUST_ERANGE2(X, Y) \
do { \
if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \
(Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \
if (errno == 0) \
errno = ERANGE; \
} \
else if (errno == ERANGE) \
errno = 0; \
} while(0)
This diff is collapsed.
......@@ -17,6 +17,7 @@
#include <cstring>
#include <gmp.h>
#include "capi/types.h"
#include "core/types.h"
#include "runtime/inline/boxing.h"
#include "runtime/long.h"
......@@ -24,6 +25,11 @@
#include "runtime/types.h"
#include "runtime/util.h"
extern "C" PyObject* float_hex(PyObject* v) noexcept;
extern "C" PyObject* float_fromhex(PyObject* cls, PyObject* arg) noexcept;
extern "C" PyObject* float_as_integer_ratio(PyObject* v, PyObject* unused) noexcept;
extern "C" PyObject* float_is_integer(PyObject* v) noexcept;
namespace pyston {
extern "C" PyObject* PyFloat_FromDouble(double d) noexcept {
......@@ -1424,6 +1430,12 @@ exit:
return result;
}
static PyMethodDef float_methods[] = { { "hex", (PyCFunction)float_hex, METH_NOARGS, NULL },
{ "fromhex", (PyCFunction)float_fromhex, METH_O | METH_CLASS, NULL },
{ "as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, NULL },
{ "is_integer", (PyCFunction)float_is_integer, METH_NOARGS, NULL } };
void setupFloat() {
_addFunc("__add__", BOXED_FLOAT, (void*)floatAddFloat, (void*)floatAddInt, (void*)floatAdd);
float_cls->giveAttr("__radd__", float_cls->getattr("__add__"));
......@@ -1472,6 +1484,10 @@ void setupFloat() {
new BoxedClassmethod(new BoxedBuiltinFunctionOrMethod(
boxRTFunction((void*)floatGetFormat, STR, 2), "__getformat__", floatGetFormatDoc)));
for (auto& md : float_methods) {
float_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, float_cls));
}
float_cls->freeze();
floatFormatInit();
......
......@@ -407,6 +407,8 @@ public:
DEFAULT_CLASS_SIMPLE(float_cls);
};
static_assert(sizeof(BoxedFloat) == sizeof(PyFloatObject), "");
static_assert(offsetof(BoxedFloat, d) == offsetof(PyFloatObject, ob_fval), "");
class BoxedComplex : public Box {
public:
......
......@@ -58,3 +58,9 @@ try:
float.__getformat__('oooga booga boooga')
except Exception as e:
print e.message
print float.fromhex("f0.04a")
print (5.0).hex()
print (0.5).as_integer_ratio()
print (0.5).is_integer()
print (1.0).is_integer()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment