--- icu.orig/source/common/putil.c 2008-05-19 13:33:04.000000000 +0100 +++ icu/source/common/putil.c 2008-05-19 14:18:15.000000000 +0100 @@ -159,30 +159,46 @@ # define U_POSIX_LOCALE 1 #endif -/* - WARNING! u_topNBytesOfDouble and u_bottomNBytesOfDouble - can't be properly optimized by the gcc compiler sometimes (i.e. gcc 3.2). -*/ #if !IEEE_754 -static char* -u_topNBytesOfDouble(double* d, int n) +static uint32_t +u_topOfDoubleAsUint32(double d) { -#if U_IS_BIG_ENDIAN - return (char*)d; -#else - return (char*)(d + 1) - n; -#endif + union + { + double d; + uint32_t i[2]; + } u; + + u.d = d; + return u.i + [ +# if U_IS_BIG_ENDIAN + 0 +# else + 1 +# endif + ]; } #endif -static char* -u_bottomNBytesOfDouble(double* d, int n) +static uint32_t +u_bottomOfDoubleAsUint32(double d) { -#if U_IS_BIG_ENDIAN - return (char*)(d + 1) - n; -#else - return (char*)d; -#endif + union + { + double d; + uint32_t i[2]; + } u; + + u.d = d; + return u.i + [ +# if U_IS_BIG_ENDIAN + 1 +# else + 0 +# endif + ]; } #if defined(U_WINDOWS) @@ -259,10 +274,8 @@ return (UBool)((convertedNumber.i64 & U_INT64_MAX) > gInf.i64); #elif defined(OS390) - uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number, - sizeof(uint32_t)); - uint32_t lowBits = *(uint32_t*)u_bottomNBytesOfDouble(&number, - sizeof(uint32_t)); + uint32_t highBits = u_topOfDoubleAsUint32(number); + uint32_t lowBits = u_bottomOfDoubleAsUint32(number); return ((highBits & 0x7F080000L) == 0x7F080000L) && (lowBits == 0x00000000L); @@ -284,10 +297,8 @@ /* Infinity is exactly 0x7FF0000000000000U. */ return (UBool)((convertedNumber.i64 & U_INT64_MAX) == gInf.i64); #elif defined(OS390) - uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number, - sizeof(uint32_t)); - uint32_t lowBits = *(uint32_t*)u_bottomNBytesOfDouble(&number, - sizeof(uint32_t)); + uint32_t highBits = u_topOfDoubleAsUint32(number); + uint32_t lowBits = u_bottomOfDoubleAsUint32(number); return ((highBits & ~SIGN) == 0x70FF0000L) && (lowBits == 0x00000000L); @@ -316,8 +327,7 @@ return (UBool)(number < 0 && uprv_isInfinite(number)); #else - uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number, - sizeof(uint32_t)); + uint32_t highBits = u_topOfDoubleAsUint32(number); return((highBits & SIGN) && uprv_isInfinite(number)); #endif @@ -409,7 +419,7 @@ return uprv_getNaN(); /* check for -0 and 0*/ - lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&x, sizeof(uint32_t)); + lowBits = u_bottomOfDoubleAsUint32(x); if(x == 0.0 && y == 0.0 && (lowBits & SIGN)) return y; @@ -430,7 +440,7 @@ return uprv_getNaN(); /* check for -0 and 0*/ - lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&y, sizeof(uint32_t)); + lowBits = u_bottomOfDoubleAsUint32(y); if(x == 0.0 && y == 0.0 && (lowBits & SIGN)) return y; @@ -459,7 +469,7 @@ if(uprv_isInfinite(d)) return uprv_getInfinity(); - lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&d, sizeof(uint32_t)); + lowBits = u_bottomOfDoubleAsUint32(d); if( (d == 0.0 && (lowBits & SIGN)) || d < 0) return ceil(d); else