From b437d2f1f13e11228129174e8d41d5ae187b16e8 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Mon, 20 Jun 2005 16:16:54 -0500 Subject: [svn-r10962] Purpose: Solve the Difference of Compiler and Library Description: In this data conversion test, from floating number to floating number, when the source is bigger than the destination, overflow may happen. The library assign INFINITY while compiler's behavior is undefined. A compiler like SGI assigns the maximal value for the destination. Solution: When this situation occurs, simply check if the destination is INFINITY instead of comparing values. Platforms tested: modi4 and h5committest. --- test/dt_arith.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/test/dt_arith.c b/test/dt_arith.c index fd470c5..e8fb1cd 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -369,6 +369,8 @@ static int without_hardware_g = 0; void some_dummy_func(float x); static hbool_t overflows(unsigned char *origin_bits, hid_t src_id, size_t dst_num_bits); static int my_isnan(dtype_t type, void *val); +static int my_isinf(dtype_t type, int endian, unsigned char *val, size_t size, + size_t mpos, size_t msize, size_t epos, size_t esize); /*------------------------------------------------------------------------- * Function: fpe_handler @@ -2378,6 +2380,43 @@ my_isnan(dtype_t type, void *val) /*------------------------------------------------------------------------- + * Function: my_isinf + * + * Purpose: Determines whether VAL points to +/-infinity. + * + * Return: TRUE or FALSE + * + * Programmer: Raymond Lu + * Monday, June 20, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +my_isinf(dtype_t type, int endian, unsigned char *val, size_t size, + size_t mpos, size_t msize, size_t epos, size_t esize) +{ + unsigned char *bits; + int retval = 0; + int i; + ssize_t ret1=0, ret2=0; + + bits = (unsigned char*)calloc(1, size); + for (i=0; i FLT_MAX; } else if (FLT_DOUBLE==dst_type) { hw_d = *((double*)aligned); hw = (unsigned char*)&hw_d; @@ -2667,10 +2709,12 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst) hw_f = *((long double*)aligned); hw = (unsigned char*)&hw_f; underflow = HDfabsl(*((long double*)aligned)) < FLT_MIN; + overflow = HDfabsl(*((long double*)aligned)) > FLT_MAX; } else if (FLT_DOUBLE==dst_type) { hw_d = *((long double*)aligned); hw = (unsigned char*)&hw_d; underflow = HDfabsl(*((long double*)aligned)) < DBL_MIN; + overflow = HDfabsl(*((long double*)aligned)) > DBL_MAX; } else { hw_ld = *((long double*)aligned); hw = (unsigned char*)&hw_ld; @@ -2740,6 +2784,10 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst) * If the src number is smaller than the dst MIN float number, * consider it okay if the converted sw and hw dst are both * less than or equal to the dst MIN float number. + * If overflow happens when the src value is greater than + * the maximum dst value, the library assign INFINITY to dst. + * This might be different from what the compiler does, i.e. + * the SGI compiler assigns the dst's maximal value. */ { double check_mant[2]; @@ -2751,6 +2799,9 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst) if (underflow && HDfabsf(x) <= FLT_MIN && HDfabsf(hw_f) <= FLT_MIN) continue; /* all underflowed, no error */ + if (overflow && my_isinf(dst_type, endian, buf+j*sizeof(float), + dst_size, dst_mpos, dst_msize, dst_epos, dst_esize)) + continue; /* all overflowed, no error */ check_mant[0] = HDfrexpf(x, check_expo+0); check_mant[1] = HDfrexpf(hw_f, check_expo+1); } else if (FLT_DOUBLE==dst_type) { @@ -2759,6 +2810,9 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst) if (underflow && HDfabs(x) <= DBL_MIN && HDfabs(hw_d) <= DBL_MIN) continue; /* all underflowed, no error */ + if (overflow && my_isinf(dst_type, endian, buf+j*sizeof(double), + dst_size, dst_mpos, dst_msize, dst_epos, dst_esize)) + continue; /* all overflowed, no error */ check_mant[0] = HDfrexp(x, check_expo+0); check_mant[1] = HDfrexp(hw_d, check_expo+1); #if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE -- cgit v0.12