-
-
Save xct/112feb1951d1e43084c6b21325a09ccd to your computer and use it in GitHub Desktop.
FloatToHex (https://gregstoll.com/~gregstoll/floattohex/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Use this file as a template to start implementing a module that | |
also declares object types. All occurrences of 'Xxo' should be changed | |
to something reasonable for your objects. After that, all other | |
occurrences of 'xx' should be changed to something reasonable for your | |
module. If your module is named foo your sourcefile should be named | |
foomodule.c. | |
You will probably want to delete all references to 'x_attr' and add | |
your own types of attributes instead. Maybe you want to name your | |
local variables other than 'self'. If your object type is needed in | |
other files, you'll have to create a file "foobarobject.h"; see | |
intobject.h for an example. */ | |
#include "Python.h" | |
struct module_state { | |
PyObject *error; | |
}; | |
#if PY_MAJOR_VERSION >= 3 | |
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) | |
#else | |
#define GETSTATE(m) (&_state) | |
static struct module_state _state; | |
#endif | |
void swapFloat(float* f) { | |
char* fBytes = (char*)f; | |
for (int i = 0; i < sizeof(float)/2; ++i) { | |
int oppositeI = sizeof(float) - 1 - i; | |
char temp = fBytes[i]; | |
fBytes[i] = fBytes[oppositeI]; | |
fBytes[oppositeI] = temp; | |
} | |
} | |
void swapDouble(double* d) { | |
char* dBytes = (char*)d; | |
for (int i = 0; i < sizeof(double)/2; ++i) { | |
int oppositeI = sizeof(double) - 1 - i; | |
char temp = dBytes[i]; | |
dBytes[i] = dBytes[oppositeI]; | |
dBytes[oppositeI] = temp; | |
} | |
} | |
static PyObject * | |
FloatToHex_FloatToHex(PyObject *self, PyObject *args, PyObject *keywords) | |
{ | |
float f, fToUse; | |
int swap = 0; | |
char *keywordNames[] = {"float", "swap", NULL}; | |
if (!PyArg_ParseTupleAndKeywords(args, keywords, "f|p:floattohex", keywordNames, &f, &swap)) | |
return NULL; | |
fToUse = f; | |
if (swap != 0) { | |
swapFloat(&fToUse); | |
} | |
unsigned int i = *((unsigned int *)&fToUse); | |
return Py_BuildValue("I", i); | |
} | |
static PyObject * | |
FloatToHex_HexToFloat(PyObject *self, PyObject *args, PyObject *keywords) | |
{ | |
unsigned int i; | |
int swap = 0; | |
char *keywordNames[] = {"hex", "swap", NULL}; | |
if (!PyArg_ParseTupleAndKeywords(args, keywords, "I|p:hextofloat", keywordNames, &i, &swap)) | |
return NULL; | |
float f = *((float *)&i); | |
float fToReturn = f; | |
if (swap != 0) { | |
swapFloat(&fToReturn); | |
} | |
return Py_BuildValue("f", fToReturn); | |
} | |
static PyObject * | |
FloatToHex_DoubleToHex(PyObject *self, PyObject *args, PyObject *keywords) | |
{ | |
double d; | |
int swap = 0; | |
char *keywordNames[] = {"double", "swap", NULL}; | |
if (!PyArg_ParseTupleAndKeywords(args, keywords, "d|p:doubletohex", keywordNames, &d, &swap)) | |
return NULL; | |
double dToUse = d; | |
if (swap != 0) { | |
swapDouble(&dToUse); | |
} | |
unsigned long long l = *((unsigned long long*)&dToUse); | |
return Py_BuildValue("K", l); | |
} | |
static PyObject * | |
FloatToHex_HexToDouble(PyObject *self, PyObject *args, PyObject *keywords) | |
{ | |
unsigned long long l; | |
int swap = 0; | |
char *keywordNames[] = {"hex", "swap", NULL}; | |
if (!PyArg_ParseTupleAndKeywords(args, keywords, "K|p:hextodouble", keywordNames, &l, &swap)) | |
return NULL; | |
double d = *((double *)&l); | |
double dToReturn = d; | |
if (swap != 0) { | |
swapDouble(&dToReturn); | |
} | |
return Py_BuildValue("d", dToReturn); | |
} | |
/* List of functions defined in the module */ | |
static PyMethodDef FloatToHex_methods[] = { | |
{"floattohex", (PyCFunction)FloatToHex_FloatToHex, METH_VARARGS|METH_KEYWORDS}, | |
{"hextofloat", (PyCFunction)FloatToHex_HexToFloat, METH_VARARGS|METH_KEYWORDS}, | |
{"doubletohex", (PyCFunction)FloatToHex_DoubleToHex, METH_VARARGS|METH_KEYWORDS}, | |
{"hextodouble", (PyCFunction)FloatToHex_HexToDouble, METH_VARARGS|METH_KEYWORDS}, | |
{NULL, NULL} /* sentinel */ | |
}; | |
static int FloatToHex_traverse(PyObject *m, visitproc visit, void *arg) { | |
Py_VISIT(GETSTATE(m)->error); | |
return 0; | |
} | |
static int FloatToHex_clear(PyObject *m) { | |
Py_CLEAR(GETSTATE(m)->error); | |
return 0; | |
} | |
static struct PyModuleDef moduledef = { | |
PyModuleDef_HEAD_INIT, | |
"FloatToHex", | |
NULL, | |
sizeof(struct module_state), | |
FloatToHex_methods, | |
NULL, | |
FloatToHex_traverse, | |
FloatToHex_clear, | |
NULL | |
}; | |
/* Initialization function for the module (*must* be called initxx) */ | |
PyObject* PyInit_FloatToHex(void) | |
{ | |
/* Create the module and add the functions */ | |
PyObject* module = PyModule_Create(&moduledef); | |
if (module == NULL) | |
return NULL; | |
struct module_state *st = GETSTATE(module); | |
/* Add some symbolic constants to the module */ | |
st->error = PyErr_NewException("FloatToHex.Error", NULL, NULL); | |
if (st->error == NULL) { | |
Py_DECREF(module); | |
return NULL; | |
} | |
return module; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment