Some StrictMath functions, including exp() and log(), return incorrect values on StrongARM processor. Some others, including sin() and tan(), work just fine. In addition, System.out.println() fails to print floating point numbers correctly: # ./floattest Math.log(10)=2.302585 StrictMath.log(10)=-745.826366 Math.exp(10)=22,026.465795 StrictMath.exp(10)=1.344389 0.1+0.1=0.000003058474:0258 0.1+0.1=0.200000 # cat floattest.java import java.text.*; public class floattest { public static void print(String s, double d) { NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumFractionDigits(6); System.out.println(s + nf.format(d)); } public static void main(String args[]) { print("Math.log(10)=", Math.log(10.0)); print("StrictMath.log(10)=", StrictMath.log(10.0)); print("Math.exp(10)=", Math.exp(10.0)); print("StrictMath.exp(10)=", StrictMath.exp(10.0)); double x = 0.1 + 0.1; System.out.println("0.1+0.1=" + x); print("0.1+0.1=", x); } } Is this possibly due to a bug in Double.doubleToLongBits() (see http://lists.arm.linux.org.uk/pipermail/linux-arm/2004-June/007983.html)? The test application has been compiled with: arm-unknown-linux-gnu-gcj -c floattest.java arm-unknown-linux-gnu-gcj --main=floattest -o floattest floattest.o ... using: Reading specs from /tmp/cross/lib/gcc/arm-unknown-linux-gnu/3.4.0/specs Reading specs from /tmp/cross/lib/gcc/arm-unknown-linux-gnu/3.4.0/../../../../arm-unknown-linux-gnu/lib/libgcj.spec rename spec lib to liborig Configured with: /wrk2/jko/nobackup/arm-linux/crosstool-0.27/build/arm-unknown-linux-gnu/gcc-3.4.0-glibc-2.3.2/gcc-3.4.0/configure --target=arm-unknown-linux-gnu --host=i686-host_pc-linux-gnu --prefix=/tmp/cross --with-headers=/tmp/cross/arm-unknown-linux-gnu/include --with-local-prefix=/tmp/cross/arm-unknown-linux-gnu --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++,java --enable-shared --enable-c99 --enable-long-long Thread model: posix gcc version 3.4.0 ... and executed on a: # uname -a Linux familiar 2.4.19-rmk6-pxa1-hh30 #3 Wed Nov 12 11:07:41 EST 2003 armv4l unknown
Confirmed: doubleToLongBits, doubleToRawLongBits and longBitsToDouble are assuming that the word endianness of a double matches the word endianness of a jlong. This is an incorrect assumption on ARM's using FPA-format IEEE arithmetic. (ARM's using VFP float format are fine).
arm-linux only problems from Comment #3 . EABI targets should not have a problem .
FPA support has now been dropped in GCC.