summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2005-06-20 21:16:54 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2005-06-20 21:16:54 (GMT)
commitb437d2f1f13e11228129174e8d41d5ae187b16e8 (patch)
treefc4a096d28cb0bfe2dfe8ba70cb94cf5a3c43449
parenta704c82a74d66bbdbb48988390457ebe3995c5bb (diff)
downloadhdf5-b437d2f1f13e11228129174e8d41d5ae187b16e8.zip
hdf5-b437d2f1f13e11228129174e8d41d5ae187b16e8.tar.gz
hdf5-b437d2f1f13e11228129174e8d41d5ae187b16e8.tar.bz2
[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.
-rw-r--r--test/dt_arith.c58
1 files 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<size; i++)
+ bits[size-(i+1)] = *(val + ENDIAN(size, i));
+
+ if((ret1=H5T_bit_find(bits, mpos, msize, H5T_BIT_LSB, 1))<0 &&
+ (ret2=H5T_bit_find(bits, epos, esize, H5T_BIT_LSB, 0))<0)
+ retval = 1;
+
+ free(bits);
+
+ return retval;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: test_conv_flt_1
*
* Purpose: Test conversion of floating point values from SRC to
@@ -2414,14 +2453,15 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst)
unsigned char *buf = NULL; /*buffer for conversion */
unsigned char *saved = NULL; /*original values */
char str[256]; /*hello string */
+ void *aligned=NULL; /*aligned buffer */
float hw_f; /*hardware-converted */
double hw_d; /*hardware-converted */
- void *aligned=NULL; /*aligned buffer */
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
long double hw_ld; /*hardware-converted */
#endif
unsigned char *hw=NULL; /*ptr to hardware-conv'd*/
int underflow; /*underflow occurred */
+ int overflow; /*overflow occurred */
int uflow=0; /*underflow debug counters*/
size_t j, k; /*counters */
int endian; /*machine endianess */
@@ -2430,6 +2470,7 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst)
size_t src_esize; /* Source type's exponent size */
size_t dst_epos; /* Destination type's exponent position */
size_t dst_esize; /* Destination type's exponent size */
+ size_t dst_mpos; /* Destination type's mantissa position */
size_t dst_msize; /* Destination type's mantissa size */
size_t src_nbits; /* source length in bits */
size_t dst_nbits; /* dst length in bits */
@@ -2548,7 +2589,7 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst)
dst_nbits = H5Tget_precision(dst); /* not 8*dst_size, esp on J90 - QAK */
dst_ebias=H5Tget_ebias(dst);
H5Tget_fields(src,NULL,&src_epos,&src_esize,NULL,NULL);
- H5Tget_fields(dst,NULL,&dst_epos,&dst_esize,NULL,&dst_msize);
+ H5Tget_fields(dst,NULL,&dst_epos,&dst_esize,&dst_mpos,&dst_msize);
endian = H5Tget_order(H5T_NATIVE_FLOAT);
/* Allocate buffers */
@@ -2651,6 +2692,7 @@ test_conv_flt_1 (const char *name, int run_test, hid_t src, hid_t dst)
hw_f = (float)(*((double*)aligned));
hw = (unsigned char*)&hw_f;
underflow = HDfabs(*((double*)aligned)) < FLT_MIN;
+ overflow = HDfabs(*((double*)aligned)) > 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