It looks like a problem with Enterianism, but not with your ordinary Welshini problem with a little-understood problem. ARM sometimes uses an unusual byte order for double . From the Jean-Michel Muller et al. Floating-Point Arithmetic Handbook et al .:
... the double precision number that is closest to -7.0868766365730135 x 10^-268 is encoded by a sequence of bytes 11 22 33 44 55 66 77 88 in memory (from the lowest to the highest one) on x86 and Linux / IA-64 platforms ( they are said to be little-endian) and 88 77 66 55 44 33 22 11 on most PowerPC platforms (they are called big-endian). Some architectures, such as IA-64, ARM, and PowerPC, are said to be bidirectional. that is, they can be either low-north or big-endian depending on their configuration.
There is an exception: some ARM-based platforms. ARM processors have traditionally used a floating-point accelerator (FPA) architecture, where double-precision numbers are decomposed into two 32-bit words in ordinary order and stored according to the machine’s finiteness, i.e. a little-endian as a whole, which means that the specified number is encoded by a sequence 55 66 77 88 11 22 33 44 . ARM recently introduced a new architecture for floating point arithmetic: vector floating point (VFP), which stores words in their own byte order of the processor.
When viewed in byte order of the large end, the M_PI will have a view that looks like this:
0x400921fb54442d18
A large number, approximated by 8.6192e+97 wil, has a representation that looks like this:
0x54442d18400921fb
If you look carefully, the two 32-bit words will be replaced, but the byte order in the 32-bit words will be the same. So, apparently, the traditional “dual” ARM format seems to confuse the Qt library (or the Qt library is not configured correctly).
I'm not sure if the processor uses the traditional format, and Qt expects it to be in VFP format, or if everything is the other way around. But this seems to be one of two situations.
I also do not quite know exactly how to fix this problem - I would suggest that there is some option for Qt to handle correctly.
The following snippet will at least tell you which format for double compiler is using, which may help you narrow down what needs to be changed in Qt:
unsigned char* b; unsigned char* e; double x = -7.0868766365730135e-268; b = (unsigned char*) &x; e = b + sizeof(x); for (; b != e; ++b) { printf( "%02x ", *b); } puts("");
A regular low-rise device will appear:
11 22 33 44 55 66 77 88
Update with even more analysis:
At the moment, I can’t do any real debugging (I don’t even have access to my workstation at the moment), but looking at the Qt source available at http://qt.gitorious.org here is an additional analysis:
It looks like Qt calls the QLocalePrivate::doubleToString() function in qlocale.cpp to convert a double to alphanumeric form.
If Qt is compiled with QT_QLOCALE_USES_FCVT , then QLocalePrivate::doubleToString() will use the fcvt() platform to perform the conversion. If QT_QLOCALE_USES_FCVT not defined, then QLocalePrivate::doubleToString() terminates the call to _qdtoa() to perform the conversion. This function directly looks at the various double fields and assumes double is in strict form big-endian or little-endian (for example, using the getWord0() and getWord1() functions to get the low and high double word, respectively).
See http://qt.gitorious.org/qt/qt/blobs/HEAD/src/corelib/tools/qlocale.cpp and http://qt.gitorious.org/qt/qt/blobs/HEAD/src/corelib /tools/qlocale_tools.cpp or your own copy of the files for details.
Assuming your platform uses the traditional ARP FPA representation for double (where 32-bit double halves are stored in big-endian order, regardless of whether the common system is insignificant), I think you need to build Qt with QT_QLOCALE_USES_FCVT . I believe that all you need to do is pass the -DQT_QLOCALE_USES_FCVT parameter to the configure script when building Qt.