From 96cc43235ea92ea0f84623ad0be6d029a111c150 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Thu, 13 Jan 2005 17:01:52 -0500 Subject: [svn-r9819] Purpose: Bug fix Description: The fix of the loss problem of the last 2 bytes of mantissa on sleipnir has not been successful. It happens when converting from unsigned long long to long double. The failure has been on and off. Solution: Hard set a macro to disable unsigned long long->long double for FreeBSD until a good solution is found to solve this elusive problem. Platforms tested: sleipnir and fuss. Only sleipnir is concerned. Misc. update: --- config/freebsd | 4 ++++ configure | 19 ++++++++++--------- configure.in | 19 ++++++++++--------- test/dtypes.c | 12 ++++++------ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/config/freebsd b/config/freebsd index 51217c6..c1af4d9 100644 --- a/config/freebsd +++ b/config/freebsd @@ -43,3 +43,7 @@ if test "X-" != "X-$enable_threadsafe"; then CXXFLAGS="$CXXFLAGS -D_THREAD_SAFE" LDFLAGS="$LDFLAGS -pthread" fi + +# Temporarily hard set this variable. The problem of loss of the last 2 bytes of mantissa +# turns out to be elusive. Hard set it until a better solution is found. +hdf5_cv_ullong_to_ldouble_precision_works=${hdf5_cv_ullong_to_ldouble_precision_works='no'} diff --git a/configure b/configure index 1184ee4..e8434da 100755 --- a/configure +++ b/configure @@ -33956,29 +33956,30 @@ else unsigned long long l = 0xa601e80bda85fcefULL; long double ld; unsigned char *c1, *c2; - int endian, size; + size_t size; + int endian; int tst_value = 1; - int i; - int ret = 0; + int ret = 0; /* Determine this system's endianess */ c1 = (unsigned char*)calloc(1, sizeof(int)); - memcpy(c1, &tst_value, sizeof(int)); + memcpy((void*)c1, &tst_value, sizeof(int)); if(c1[0]==1) endian = 0; /* little endian */ else endian = 1; /* big endian */ - memset(&ld, 0, 12); + size = sizeof(long double); + memset(&ld, 0, size); ld = (long double)l; - size = sizeof(long double); - c2 = (unsigned char*)malloc(size); - memcpy(c2, &ld, size); + c2 = (unsigned char*)calloc(1, size); + memcpy((void*)c2, &ld, size); /* Test if the last 2 bytes of mantissa are lost. Mainly for FreeBSD on Intel * architecture(sleipnir) where it happens. */ - if(endian==0 && c2[0]==0 && c2[1]==0) /*little endian*/ + /*if(endian==0 && c2[0]==0 && c2[1]==0)*/ /*little endian*/ + if(endian==0 && c2[0]==0) /*little endian*/ ret = 1; free(c1); diff --git a/configure.in b/configure.in index 898bd18..b9c3846 100644 --- a/configure.in +++ b/configure.in @@ -2768,29 +2768,30 @@ AC_CACHE_VAL([hdf5_cv_ullong_to_ldouble_precision_works], unsigned long long l = 0xa601e80bda85fcefULL; long double ld; unsigned char *c1, *c2; - int endian, size; + size_t size; + int endian; int tst_value = 1; - int i; - int ret = 0; + int ret = 0; /* Determine this system's endianess */ c1 = (unsigned char*)calloc(1, sizeof(int)); - memcpy(c1, &tst_value, sizeof(int)); + memcpy((void*)c1, &tst_value, sizeof(int)); if(c1[0]==1) endian = 0; /* little endian */ else endian = 1; /* big endian */ - memset(&ld, 0, 12); + size = sizeof(long double); + memset(&ld, 0, size); ld = (long double)l; - size = sizeof(long double); - c2 = (unsigned char*)malloc(size); - memcpy(c2, &ld, size); + c2 = (unsigned char*)calloc(1, size); + memcpy((void*)c2, &ld, size); /* Test if the last 2 bytes of mantissa are lost. Mainly for FreeBSD on Intel * architecture(sleipnir) where it happens. */ - if(endian==0 && c2[0]==0 && c2[1]==0) /*little endian*/ + /*if(endian==0 && c2[0]==0 && c2[1]==0)*/ /*little endian*/ + if(endian==0 && c2[0]==0) /*little endian*/ ret = 1; free(c1); diff --git a/test/dtypes.c b/test/dtypes.c index 684ed19..a60d968 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -5859,8 +5859,8 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) long double tmp_s, tmp_h; HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(long double)); HDmemcpy(&tmp_h,&hw[0],sizeof(long double)); - /*Don't compare the last 2 bytes of mantissa*/ - if(!HDmemcmp(&tmp_s+3, &tmp_h+3, sizeof(long double)-3)) + /*Don't compare the last 3 bytes of mantissa*/ + if(!HDmemcmp(&tmp_s+4, &tmp_h+4, sizeof(long double)-4)) continue; /*no error*/ } #endif /*end H5_ULLONG_TO_LDOUBLE_PRECISION_WORKS*/ @@ -6397,7 +6397,9 @@ run_int_float_conv(const char *name) #if H5_SIZEOF_LONG_LONG!=H5_SIZEOF_LONG nerrors += test_conv_int_float(name, H5T_NATIVE_LLONG, H5T_NATIVE_LDOUBLE); #ifdef H5_ULLONG_TO_FP_CAST_WORKS +#ifdef H5_ULLONG_TO_LDOUBLE_PRECISION_WORKS nerrors += test_conv_int_float(name, H5T_NATIVE_ULLONG, H5T_NATIVE_LDOUBLE); +#endif /*H5_ULLONG_TO_LDOUBLE_PRECISION_WORKS*/ #else /* H5_ULLONG_TO_FP_CAST_WORKS */ { char str[256]; /*hello string */ @@ -6446,7 +6448,7 @@ static int run_float_int_conv(const char *name) { int nerrors = 0; -#ifndef TMP + nerrors += test_conv_int_float(name, H5T_NATIVE_FLOAT, H5T_NATIVE_SCHAR); nerrors += test_conv_int_float(name, H5T_NATIVE_DOUBLE, H5T_NATIVE_SCHAR); @@ -6507,7 +6509,6 @@ run_float_int_conv(const char *name) #endif /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ #endif -#endif /*TMP*/ if(!strcmp(name, "sw")) { #if H5_SW_LDOUBLE_TO_INTEGER_WORKS #if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE @@ -6984,7 +6985,7 @@ main(void) if (ALIGNMENT) printf("Testing non-aligned conversions (ALIGNMENT=%d)....\n", ALIGNMENT); -#ifndef TMP + /* Do the tests */ nerrors += test_classes(); nerrors += test_copy(); @@ -7060,7 +7061,6 @@ main(void) /* Test software float-integer conversion functions */ nerrors += run_float_int_conv("sw"); -#endif /*TMP*/ /* Test software integer-float conversion functions */ nerrors += run_int_float_conv("sw"); -- cgit v0.12