Index: Objects/floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.134 diff -c -r2.134 floatobject.c *** Objects/floatobject.c 23 Sep 2004 19:22:41 -0000 2.134 --- Objects/floatobject.c 12 Apr 2005 07:20:01 -0000 *************** *** 1075,1080 **** --- 1075,1120 ---- float_new, /* tp_new */ }; + /* this is for the benefit of the pack/unpack routines below */ + + typedef enum { + unknown_format, ieee_big_endian_format, ieee_little_endian_format + } float_format_type; + + static float_format_type double_format, float_format; + + void + _PyFloat_Init(void) + { + #if SIZEOF_DOUBLE == 8 + { + double x = 1.5; + if (memcmp(&x, "\x3f\xf8\x00\x00\x00\x00\x00\x00", 8) == 0) + double_format = ieee_big_endian_format; + else if (memcmp(&x, "\x00\x00\x00\x00\x00\x00\xf8\x3f", 8) == 0) + double_format = ieee_big_endian_format; + else + double_format = unknown_format; + } + #else + double_format = unknown_format; + #endif + + #if SIZEOF_FLOAT == 4 + { + float y = 1.5; + if (memcmp(&y, "\x3f\xc0\x00\x00", 4) == 0) + float_format = ieee_big_endian_format; + else if (memcmp(&y, "\x00\x00\xc0\x3f", 4) == 0) + float_format = ieee_big_endian_format; + else + float_format = unknown_format; + } + #else + float_format = unknown_format; + #endif + } + void PyFloat_Fini(void) { *************** *** 1162,1467 **** int _PyFloat_Pack4(double x, unsigned char *p, int le) { ! unsigned char sign; ! int e; ! double f; ! unsigned int fbits; ! int incr = 1; ! if (le) { ! p += 3; ! incr = -1; ! } ! if (x < 0) { ! sign = 1; ! x = -x; ! } ! else ! sign = 0; ! f = frexp(x, &e); ! /* Normalize f to be in the range [1.0, 2.0) */ ! if (0.5 <= f && f < 1.0) { ! f *= 2.0; ! e--; ! } ! else if (f == 0.0) ! e = 0; ! else { ! PyErr_SetString(PyExc_SystemError, ! "frexp() result out of range"); return -1; } ! ! if (e >= 128) ! goto Overflow; ! else if (e < -126) { ! /* Gradual underflow */ ! f = ldexp(f, 126 + e); ! e = 0; ! } ! else if (!(e == 0 && f == 0.0)) { ! e += 127; ! f -= 1.0; /* Get rid of leading 1 */ ! } ! ! f *= 8388608.0; /* 2**23 */ ! fbits = (unsigned int)(f + 0.5); /* Round */ ! assert(fbits <= 8388608); ! if (fbits >> 23) { ! /* The carry propagated out of a string of 23 1 bits. */ ! fbits = 0; ! ++e; ! if (e >= 255) ! goto Overflow; } - - /* First byte */ - *p = (sign << 7) | (e >> 1); - p += incr; - - /* Second byte */ - *p = (char) (((e & 1) << 7) | (fbits >> 16)); - p += incr; - - /* Third byte */ - *p = (fbits >> 8) & 0xFF; - p += incr; - - /* Fourth byte */ - *p = fbits & 0xFF; - - /* Done */ - return 0; - - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with f format"); - return -1; } int _PyFloat_Pack8(double x, unsigned char *p, int le) { ! unsigned char sign; ! int e; ! double f; ! unsigned int fhi, flo; ! int incr = 1; ! if (le) { ! p += 7; ! incr = -1; ! } ! if (x < 0) { ! sign = 1; ! x = -x; ! } ! else ! sign = 0; ! f = frexp(x, &e); ! /* Normalize f to be in the range [1.0, 2.0) */ ! if (0.5 <= f && f < 1.0) { ! f *= 2.0; ! e--; ! } ! else if (f == 0.0) ! e = 0; ! else { ! PyErr_SetString(PyExc_SystemError, ! "frexp() result out of range"); return -1; } ! if (e >= 1024) ! goto Overflow; ! else if (e < -1022) { ! /* Gradual underflow */ ! f = ldexp(f, 1022 + e); ! e = 0; ! } ! else if (!(e == 0 && f == 0.0)) { ! e += 1023; ! f -= 1.0; /* Get rid of leading 1 */ ! } ! ! /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ ! f *= 268435456.0; /* 2**28 */ ! fhi = (unsigned int)f; /* Truncate */ ! assert(fhi < 268435456); ! ! f -= (double)fhi; ! f *= 16777216.0; /* 2**24 */ ! flo = (unsigned int)(f + 0.5); /* Round */ ! assert(flo <= 16777216); ! if (flo >> 24) { ! /* The carry propagated out of a string of 24 1 bits. */ ! flo = 0; ! ++fhi; ! if (fhi >> 28) { ! /* And it also progagated out of the next 28 bits. */ ! fhi = 0; ! ++e; ! if (e >= 2047) ! goto Overflow; } } - - /* First byte */ - *p = (sign << 7) | (e >> 4); - p += incr; - - /* Second byte */ - *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); - p += incr; - - /* Third byte */ - *p = (fhi >> 16) & 0xFF; - p += incr; - - /* Fourth byte */ - *p = (fhi >> 8) & 0xFF; - p += incr; - - /* Fifth byte */ - *p = fhi & 0xFF; - p += incr; - - /* Sixth byte */ - *p = (flo >> 16) & 0xFF; - p += incr; - - /* Seventh byte */ - *p = (flo >> 8) & 0xFF; - p += incr; - - /* Eighth byte */ - *p = flo & 0xFF; - p += incr; - - /* Done */ - return 0; - - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with d format"); - return -1; } double _PyFloat_Unpack4(const unsigned char *p, int le) { ! unsigned char sign; ! int e; ! unsigned int f; ! double x; ! int incr = 1; ! ! if (le) { ! p += 3; ! incr = -1; ! } ! ! /* First byte */ ! sign = (*p >> 7) & 1; ! e = (*p & 0x7F) << 1; ! p += incr; ! ! /* Second byte */ ! e |= (*p >> 7) & 1; ! f = (*p & 0x7F) << 16; ! p += incr; ! ! /* Third byte */ ! f |= *p << 8; ! p += incr; ! ! /* Fourth byte */ ! f |= *p; ! ! x = (double)f / 8388608.0; ! ! /* XXX This sadly ignores Inf/NaN issues */ ! if (e == 0) ! e = -126; ! else { ! x += 1.0; ! e -= 127; ! } ! x = ldexp(x, e); ! if (sign) ! x = -x; ! return x; } double _PyFloat_Unpack8(const unsigned char *p, int le) { ! unsigned char sign; ! int e; ! unsigned int fhi, flo; ! double x; ! int incr = 1; ! ! if (le) { ! p += 7; ! incr = -1; ! } ! ! /* First byte */ ! sign = (*p >> 7) & 1; ! e = (*p & 0x7F) << 4; ! p += incr; ! ! /* Second byte */ ! e |= (*p >> 4) & 0xF; ! fhi = (*p & 0xF) << 24; ! p += incr; ! ! /* Third byte */ ! fhi |= *p << 16; ! p += incr; ! ! /* Fourth byte */ ! fhi |= *p << 8; ! p += incr; ! ! /* Fifth byte */ ! fhi |= *p; ! p += incr; ! ! /* Sixth byte */ ! flo = *p << 16; ! p += incr; ! ! /* Seventh byte */ ! flo |= *p << 8; ! p += incr; ! ! /* Eighth byte */ ! flo |= *p; ! ! x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ ! x /= 268435456.0; /* 2**28 */ ! ! /* XXX This sadly ignores Inf/NaN */ ! if (e == 0) ! e = -1022; ! else { ! x += 1.0; ! e -= 1023; ! } ! x = ldexp(x, e); ! if (sign) ! x = -x; ! return x; } --- 1202,1580 ---- int _PyFloat_Pack4(double x, unsigned char *p, int le) { ! if (float_format == unknown_format) { ! unsigned char sign; ! int e; ! double f; ! unsigned int fbits; ! int incr = 1; ! ! if (le) { ! p += 3; ! incr = -1; ! } ! if (x < 0) { ! sign = 1; ! x = -x; ! } ! else ! sign = 0; ! f = frexp(x, &e); ! /* Normalize f to be in the range [1.0, 2.0) */ ! if (0.5 <= f && f < 1.0) { ! f *= 2.0; ! e--; ! } ! else if (f == 0.0) ! e = 0; ! else { ! PyErr_SetString(PyExc_SystemError, ! "frexp() result out of range"); ! return -1; ! } ! if (e >= 128) ! goto Overflow; ! else if (e < -126) { ! /* Gradual underflow */ ! f = ldexp(f, 126 + e); ! e = 0; ! } ! else if (!(e == 0 && f == 0.0)) { ! e += 127; ! f -= 1.0; /* Get rid of leading 1 */ ! } ! ! f *= 8388608.0; /* 2**23 */ ! fbits = (unsigned int)(f + 0.5); /* Round */ ! assert(fbits <= 8388608); ! if (fbits >> 23) { ! /* The carry propagated out of a string of 23 1 bits. */ ! fbits = 0; ! ++e; ! if (e >= 255) ! goto Overflow; ! } ! ! /* First byte */ ! *p = (sign << 7) | (e >> 1); ! p += incr; ! ! /* Second byte */ ! *p = (char) (((e & 1) << 7) | (fbits >> 16)); ! p += incr; ! ! /* Third byte */ ! *p = (fbits >> 8) & 0xFF; ! p += incr; ! ! /* Fourth byte */ ! *p = fbits & 0xFF; ! ! /* Done */ ! return 0; ! ! Overflow: ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with f format"); return -1; } ! else { ! float y = x; ! const char *s = (char*)&y; ! int i, incr = 1; ! ! if ((float_format == ieee_little_endian_format && !le) ! || (float_format == ieee_big_endian_format && le)) { ! p += 3; ! incr = -1; ! } ! ! for (i = 0; i < 4; i++) { ! *p = *s++; ! p += incr; ! } ! return 0; } } int _PyFloat_Pack8(double x, unsigned char *p, int le) { ! if (double_format == unknown_format) { ! unsigned char sign; ! int e; ! double f; ! unsigned int fhi, flo; ! int incr = 1; ! ! if (le) { ! p += 7; ! incr = -1; ! } ! if (x < 0) { ! sign = 1; ! x = -x; ! } ! else ! sign = 0; ! f = frexp(x, &e); ! /* Normalize f to be in the range [1.0, 2.0) */ ! if (0.5 <= f && f < 1.0) { ! f *= 2.0; ! e--; ! } ! else if (f == 0.0) ! e = 0; ! else { ! PyErr_SetString(PyExc_SystemError, ! "frexp() result out of range"); ! return -1; ! } ! if (e >= 1024) ! goto Overflow; ! else if (e < -1022) { ! /* Gradual underflow */ ! f = ldexp(f, 1022 + e); ! e = 0; ! } ! else if (!(e == 0 && f == 0.0)) { ! e += 1023; ! f -= 1.0; /* Get rid of leading 1 */ ! } ! ! /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ ! f *= 268435456.0; /* 2**28 */ ! fhi = (unsigned int)f; /* Truncate */ ! assert(fhi < 268435456); ! ! f -= (double)fhi; ! f *= 16777216.0; /* 2**24 */ ! flo = (unsigned int)(f + 0.5); /* Round */ ! assert(flo <= 16777216); ! if (flo >> 24) { ! /* The carry propagated out of a string of 24 1 bits. */ ! flo = 0; ! ++fhi; ! if (fhi >> 28) { ! /* And it also progagated out of the next 28 bits. */ ! fhi = 0; ! ++e; ! if (e >= 2047) ! goto Overflow; ! } ! } ! ! /* First byte */ ! *p = (sign << 7) | (e >> 4); ! p += incr; ! ! /* Second byte */ ! *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); ! p += incr; ! ! /* Third byte */ ! *p = (fhi >> 16) & 0xFF; ! p += incr; ! ! /* Fourth byte */ ! *p = (fhi >> 8) & 0xFF; ! p += incr; ! ! /* Fifth byte */ ! *p = fhi & 0xFF; ! p += incr; ! ! /* Sixth byte */ ! *p = (flo >> 16) & 0xFF; ! p += incr; ! ! /* Seventh byte */ ! *p = (flo >> 8) & 0xFF; ! p += incr; ! ! /* Eighth byte */ ! *p = flo & 0xFF; ! p += incr; ! ! /* Done */ ! return 0; ! ! Overflow: ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with d format"); return -1; } + else { + const char *s = (char*)&x; + int i, incr = 1; ! if ((double_format == ieee_little_endian_format && !le) ! || (double_format == ieee_big_endian_format && le)) { ! p += 7; ! incr = -1; } + + for (i = 0; i < 8; i++) { + *p = *s++; + p += incr; + } + return 0; } } double _PyFloat_Unpack4(const unsigned char *p, int le) { ! if (float_format == unknown_format) { ! unsigned char sign; ! int e; ! unsigned int f; ! double x; ! int incr = 1; ! ! if (le) { ! p += 3; ! incr = -1; ! } ! ! /* First byte */ ! sign = (*p >> 7) & 1; ! e = (*p & 0x7F) << 1; ! p += incr; ! ! /* Second byte */ ! e |= (*p >> 7) & 1; ! f = (*p & 0x7F) << 16; ! p += incr; ! ! /* Third byte */ ! f |= *p << 8; ! p += incr; ! ! /* Fourth byte */ ! f |= *p; ! ! x = (double)f / 8388608.0; ! ! /* XXX This sadly ignores Inf/NaN issues */ ! if (e == 0) ! e = -126; ! else { ! x += 1.0; ! e -= 127; ! } ! x = ldexp(x, e); ! ! if (sign) ! x = -x; ! return x; ! } ! else { ! if ((float_format == ieee_little_endian_format && !le) ! || (float_format == ieee_big_endian_format && le)) { ! char buf[8]; ! char *d = &buf[3]; ! int i; ! for (i = 0; i < 4; i++) { ! *d-- = *p++; ! } ! return *(float*)&buf[0]; ! } ! else { ! return *(float*)p; ! } ! } } double _PyFloat_Unpack8(const unsigned char *p, int le) { ! if (double_format == ieee_big_endian_format) { ! unsigned char sign; ! int e; ! unsigned int fhi, flo; ! double x; ! int incr = 1; ! ! if (le) { ! p += 7; ! incr = -1; ! } ! /* First byte */ ! sign = (*p >> 7) & 1; ! e = (*p & 0x7F) << 4; ! p += incr; ! ! /* Second byte */ ! e |= (*p >> 4) & 0xF; ! fhi = (*p & 0xF) << 24; ! p += incr; ! ! /* Third byte */ ! fhi |= *p << 16; ! p += incr; ! ! /* Fourth byte */ ! fhi |= *p << 8; ! p += incr; ! ! /* Fifth byte */ ! fhi |= *p; ! p += incr; ! ! /* Sixth byte */ ! flo = *p << 16; ! p += incr; ! ! /* Seventh byte */ ! flo |= *p << 8; ! p += incr; ! ! /* Eighth byte */ ! flo |= *p; ! ! x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ ! x /= 268435456.0; /* 2**28 */ ! ! /* XXX This sadly ignores Inf/NaN */ ! if (e == 0) ! e = -1022; ! else { ! x += 1.0; ! e -= 1023; ! } ! x = ldexp(x, e); ! ! if (sign) ! x = -x; ! return x; ! } ! else { ! if ((double_format == ieee_little_endian_format && !le) ! || (double_format == ieee_big_endian_format && le)) { ! char buf[8]; ! char *d = &buf[7]; ! int i; ! ! for (i = 0; i < 8; i++) { ! *d-- = *p++; ! } ! return *(double*)&buf[0]; ! } ! else { ! return *(double*)p; ! } ! } } Index: Include/pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.65 diff -c -r2.65 pythonrun.h *** Include/pythonrun.h 7 Oct 2004 03:58:06 -0000 2.65 --- Include/pythonrun.h 12 Apr 2005 07:20:03 -0000 *************** *** 105,110 **** --- 105,111 ---- PyAPI_FUNC(void) _PyImportHooks_Init(void); PyAPI_FUNC(int) _PyFrame_Init(void); PyAPI_FUNC(int) _PyInt_Init(void); + PyAPI_FUNC(void) _PyFloat_Init(void); /* Various internal finalizers */ PyAPI_FUNC(void) _PyExc_Fini(void); Index: Python/pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.213 diff -c -r2.213 pythonrun.c *** Python/pythonrun.c 29 Mar 2005 13:36:16 -0000 2.213 --- Python/pythonrun.c 12 Apr 2005 07:20:15 -0000 *************** *** 172,177 **** --- 172,179 ---- if (!_PyInt_Init()) Py_FatalError("Py_Initialize: can't init ints"); + _PyFloat_Init(); + interp->modules = PyDict_New(); if (interp->modules == NULL) Py_FatalError("Py_Initialize: can't make modules dictionary");