diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2005-01-06 18:17:59 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2005-01-06 18:17:59 (GMT) |
commit | 82f6a72ec92fa12371c386c70c607dd8957ce8b6 (patch) | |
tree | 41e4cf0b57c5a123ded9dbe4c3f951b4ae818f4a | |
parent | 03edfaa6e90c150e017b2e8d6a6c0772b2a2650c (diff) | |
download | hdf5-82f6a72ec92fa12371c386c70c607dd8957ce8b6.zip hdf5-82f6a72ec92fa12371c386c70c607dd8957ce8b6.tar.gz hdf5-82f6a72ec92fa12371c386c70c607dd8957ce8b6.tar.bz2 |
[svn-r9755] Purpose: New feature
Description: Start to support software conversion between long double and
all integers.
Solution: No major changes to the algorithm. Changes to configure is to
exclude SGI for long double to integers test because there're too many problems
in their compiler.
Platforms tested: h5committest, modi4, fuss, Teragrid, arabica
Misc. update: RELEASE.txt
-rw-r--r-- | config/irix5.x | 19 | ||||
-rw-r--r-- | config/irix6.x | 14 | ||||
-rwxr-xr-x | configure | 36 | ||||
-rw-r--r-- | configure.in | 33 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 2 | ||||
-rw-r--r-- | src/H5Tconv.c | 54 | ||||
-rw-r--r-- | src/H5config.h.in | 4 | ||||
-rw-r--r-- | test/dtypes.c | 403 |
8 files changed, 372 insertions, 193 deletions
diff --git a/config/irix5.x b/config/irix5.x index 3624e7f..77b35c8 100644 --- a/config/irix5.x +++ b/config/irix5.x @@ -48,3 +48,22 @@ case "X-$CC_BASENAME" in PROFILE_CPPFLAGS= ;; esac + +# Hard set flag to indicate that the 'unsigned long long' to floating-point +# value conversion are broken by the compilers (as of 4/27/04 - QAK) +hdf5_cv_sw_ulong_to_fp_bottom_bit_works=${hdf5_cv_sw_ulong_to_fp_bottom_bit_works='no'} + +# Set flag to avoid conversion between 'long double' and integers because of +# SGI's compiler problems. For both IRIX64 6.5 and IRIX 6.5, the compilers +# have the following problems, +# long double -> signed char : incorrect rounding +# long double -> unsigned char : incorrect rounding +# long double -> short : incorrect rounding +# long double -> unsigned short : incorrect rounding +# long double -> long or long long: incorrect value +# long double -> unsigned long or long long : incorrect value +# +# long or long long -> long double : correct value but incorrect bit pattern +# unsigned long or long long -> long double : correct value but incorrect bit pattern +# (1/5/05 - SLU) +hdf5_cv_sw_ldouble_to_int_works=${hdf5_cv_sw_ldouble_to_int_works='no'} diff --git a/config/irix6.x b/config/irix6.x index 2481e1e..293f2c8 100644 --- a/config/irix6.x +++ b/config/irix6.x @@ -146,3 +146,17 @@ fi # value conversion are broken by the compilers (as of 4/27/04 - QAK) hdf5_cv_sw_ulong_to_fp_bottom_bit_works=${hdf5_cv_sw_ulong_to_fp_bottom_bit_works='no'} +# Set flag to avoid conversion between 'long double' and integers because of +# SGI's compiler problems. For both IRIX64 6.5 and IRIX 6.5, the compilers +# have the following problems, +# long double -> signed char : incorrect rounding +# long double -> unsigned char : incorrect rounding +# long double -> short : incorrect rounding +# long double -> unsigned short : incorrect rounding +# long double -> long or long long: incorrect value +# long double -> unsigned long or long long : incorrect value +# +# long or long long -> long double : correct value but incorrect bit pattern +# unsigned long or long long -> long double : correct value but incorrect bit pattern +# (1/5/05 - SLU) +hdf5_cv_sw_ldouble_to_int_works=${hdf5_cv_sw_ldouble_to_int_works='no'} @@ -33538,6 +33538,28 @@ else echo "${ECHO_T}no" >&6 fi +echo "$as_me:$LINENO: checking if accurately converting between long double and integers works" >&5 +echo $ECHO_N "checking if accurately converting between long double and integers works... $ECHO_C" >&6 +if test "${hdf5_cv_sw_ldouble_to_int_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + hdf5_cv_sw_ldouble_to_int_works=yes +fi + + +if test ${hdf5_cv_sw_ldouble_to_int_works} = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define SW_LDOUBLE_TO_INT_WORKS 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + echo "$as_me:$LINENO: checking if accurately converting unsigned long long to floating-point values works" >&5 echo $ECHO_N "checking if accurately converting unsigned long long to floating-point values works... $ECHO_C" >&6 @@ -33748,18 +33770,20 @@ else { float f = 9701917572145405952.00f; double d1 = 9701917572145405952.00L; - double d2 = 2e40L; + long double d2 = 9701917572145405952.00L; + double d3 = 2e40L; unsigned long long l1 = (unsigned long long)f; unsigned long long l2 = (unsigned long long)d1; - unsigned long long l3; - unsigned long long l4 = 0x7fffffffffffffffLLU; + unsigned long long l3 = (unsigned long long)d2; + unsigned long long l4; + unsigned long long l5 = 0x7fffffffffffffffLLU; int ret = 0; - if(l1 <= l4 || l2 <= l4) + if(l1 <= l5 || l2 <= l5 || l3 <= l5) ret = 1; - l3 = (unsigned long long)d2; - if(l3 <= l4) + l4 = (unsigned long long)d3; + if(l4 <= l5) ret = 1; done: diff --git a/configure.in b/configure.in index 93354db..5d99b2a 100644 --- a/configure.in +++ b/configure.in @@ -2500,6 +2500,23 @@ else AC_MSG_RESULT([no]) fi +dnl ----------------------------------------------------------------------- +dnl Set flag to indicate that the machine can handle conversion between +dnl long double and integers. (This flag should be set "yes" for all +dnl machines except all SGIs, where some conversions are incorrect and its +dnl cache value is set "no" in its config/irix6.x file.) +dnl +AC_MSG_CHECKING([if accurately converting between long double and integers works]) +AC_CACHE_VAL([hdf5_cv_sw_ldouble_to_int_works], [hdf5_cv_sw_ldouble_to_int_works=yes]) + +if test ${hdf5_cv_sw_ldouble_to_int_works} = "yes"; then + AC_DEFINE([SW_LDOUBLE_TO_INT_WORKS], [1], + [Define if your system can accurately convert between long double and integer values.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + dnl ---------------------------------------------------------------------- dnl Set the flag to indicate that the machine can accurately convert dnl 'unsigned (long) long' values to 'float' and 'double' values. @@ -2623,7 +2640,7 @@ fi dnl ---------------------------------------------------------------------- dnl Set the flag to indicate that the machine can accurately convert -dnl 'float' or 'double' to 'unsigned (long) long' values. +dnl 'float', 'double' or 'long double' to 'unsigned (long) long' values. dnl (This flag should be set for all machines, except for HP-UX machines dnl where the maximal number for unsigned long long is 0x7fffffffffffffff dnl during conversion. @@ -2636,18 +2653,20 @@ AC_CACHE_VAL([hdf5_cv_fp_to_ullong_right_maximum], { float f = 9701917572145405952.00f; double d1 = 9701917572145405952.00L; - double d2 = 2e40L; + long double d2 = 9701917572145405952.00L; + double d3 = 2e40L; unsigned long long l1 = (unsigned long long)f; unsigned long long l2 = (unsigned long long)d1; - unsigned long long l3; - unsigned long long l4 = 0x7fffffffffffffffLLU; + unsigned long long l3 = (unsigned long long)d2; + unsigned long long l4; + unsigned long long l5 = 0x7fffffffffffffffLLU; int ret = 0; - if(l1 <= l4 || l2 <= l4) + if(l1 <= l5 || l2 <= l5 || l3 <= l5) ret = 1; - l3 = (unsigned long long)d2; - if(l3 <= l4) + l4 = (unsigned long long)d3; + if(l4 <= l5) ret = 1; done: diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 01bca50..2130958 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -36,6 +36,8 @@ New Features Configuration: -------------- + - Started to support software conversion between long double and + integers. Hardware conversion will come very soon. SLU - 2005/1/6 - Intel v8.0 compiler would infinite loop when compiling some test code with -O3 option. Changed enable-production default compiler option to -O2. AKC - 2004/12/06 diff --git a/src/H5Tconv.c b/src/H5Tconv.c index a9c463f..df87a2d 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -8914,10 +8914,7 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * the source exponent bias. */ if (0==expo || H5T_NORM_NONE==src.u.f.norm) { - bitno = H5T_bit_find(s, src.u.f.mpos, src.u.f.msize, - H5T_BIT_MSB, TRUE); - assert(bitno>=0); - expo -= (src.u.f.ebias-1) + (src.u.f.msize-bitno); + expo -= (src.u.f.ebias-1); } else if (H5T_NORM_IMPLIED==src.u.f.norm) { expo -= src.u.f.ebias; } else { @@ -8948,7 +8945,7 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * Shift mantissa part by exponent minus mantissa size(right shift), * or by mantissa size minus exponent(left shift). Example: Sequence * 10...010111, expo=20, expo-msize=-3. Right-shift the sequence, we get - * 00010...01. The last three ones were dropped. + * 00010...10. The last three bits were dropped. */ H5T_bit_shift(int_buf, (ssize_t)(expo-src.u.f.msize), 0, buf_size*8); @@ -8959,17 +8956,10 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (expo < src.u.f.msize && cb_struct.func) truncated = TRUE; - /* Convert to integer representation if negative. - * equivalent to ~(value - 1). - */ - if(sign) { - H5T_bit_dec(int_buf, 0, 8*buf_size); - H5T_bit_neg(int_buf, 0, 8*buf_size); - } - /* * What is the bit position for the most significant bit(MSB) of S - * which is set? + * which is set? This is checked before converted to negative + * integer. */ sfirst = H5T_bit_find(int_buf, 0, 8*buf_size, H5T_BIT_MSB, TRUE); first = (size_t)sfirst; @@ -9041,9 +9031,13 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, src_id, dst_id, src_rev, d, cb_struct.user_data); } - if(except_ret == H5T_CONV_UNHANDLED) { - /*copy source value into it if case is ignored by user handler*/ - H5T_bit_copy (d, dst.offset, int_buf, 0, first+1); + if(except_ret == H5T_CONV_UNHANDLED) { /*If this case ignored by user handler*/ + /*Convert to integer representation. Equivalent to ~(value - 1).*/ + H5T_bit_dec(int_buf, 0, 8*buf_size); + H5T_bit_neg(int_buf, 0, 8*buf_size); + + /*copy source value into destiny*/ + H5T_bit_copy (d, dst.offset, int_buf, 0, dst.prec-1); H5T_bit_set (d, (dst.offset + dst.prec-1), 1, TRUE); } else if(except_ret == H5T_CONV_ABORT) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") @@ -9055,7 +9049,8 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * the sign bit because 0x80...00 is the biggest negative value. */ if(cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); /*reverse order first*/ + /*reverse order first*/ + H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -9072,7 +9067,8 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (first >= dst.prec-1) { /*overflow*/ if(cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); /*reverse order first*/ + /*reverse order first*/ + H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -9086,7 +9082,8 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, reverse = FALSE; } else if(first < dst.prec-1) { if(truncated && cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); /*reverse order first*/ + /*reverse order first*/ + H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_TRUNCATE, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -9396,11 +9393,10 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Calculate the true destination exponent by adjusting according to - * the destination exponent bias. + * the destination exponent bias. Implied and non-implied normalization + * should be the same. */ - if (H5T_NORM_NONE==src.u.f.norm) { - expo = first + 1 + dst.u.f.ebias; - } else if (H5T_NORM_IMPLIED==src.u.f.norm) { + if (H5T_NORM_NONE==dst.u.f.norm || H5T_NORM_IMPLIED==dst.u.f.norm) { expo = first + dst.u.f.ebias; } else { assert("normalization method not implemented yet" && 0); @@ -9408,10 +9404,10 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* Handle mantissa part here */ - if (H5T_NORM_IMPLIED==src.u.f.norm) { + if (H5T_NORM_IMPLIED==dst.u.f.norm) { /* Imply first bit */ H5T_bit_set(int_buf, first, 1, 0); - } else if (H5T_NORM_NONE==src.u.f.norm) { + } else if (H5T_NORM_NONE==dst.u.f.norm) { first++; } @@ -9461,13 +9457,13 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * last f, we get 0x100...000. Treat this special case here. */ if(H5T_bit_get_d(int_buf, dst.u.f.msize, 1)) { - if (H5T_NORM_IMPLIED==src.u.f.norm) { + if (H5T_NORM_IMPLIED==dst.u.f.norm) { /* The bit at this 1's position was impled already, so this * number should be 0x200...000. We need to increment the * exponent in this case. */ expo++; - } else if (H5T_NORM_NONE==src.u.f.norm) { + } else if (H5T_NORM_NONE==dst.u.f.norm) { /* Right shift 1 bit to let the carried 1 fit in the mantissa, * and increment exponent by 1. */ @@ -9479,7 +9475,7 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } else { /* The bit sequence can fit mantissa part. Left shift to fit in from high-order of * bit position. */ - H5T_bit_shift(int_buf, (ssize_t)(dst.u.f.msize-first), 0, buf_size*8); + H5T_bit_shift(int_buf, (ssize_t)(dst.u.f.msize-first), 0, dst.u.f.msize); } diff --git a/src/H5config.h.in b/src/H5config.h.in index 4d95197..95e244d 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -516,6 +516,10 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Define if your system can accurately convert between long double and + integer values. */ +#undef SW_LDOUBLE_TO_INT_WORKS + /* Define if your system can accurately convert unsigned long long values to floating-point values. */ #undef SW_ULONG_TO_FP_BOTTOM_BIT_WORKS diff --git a/test/dtypes.c b/test/dtypes.c index e21cd23..e3c5a30 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -117,8 +117,7 @@ static int num_opaque_conversions_g = 0; #define aligned_free(M) HDfree((char*)(M)-ALIGNMENT) void some_dummy_func(float x); -static hbool_t overflows(unsigned char *origin_bits, dtype_t src_dtype, - size_t src_size_bytes, size_t dst_num_bits); +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 opaque_check(int tag_it); static herr_t convert_opaque(hid_t UNUSED st, hid_t UNUSED dt, @@ -3595,8 +3594,8 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) unsigned hw_uint; long hw_long; unsigned long hw_ulong; - long_long hw_llong; - unsigned long_long hw_ullong; + long long hw_llong; + unsigned long long hw_ullong; @@ -3691,7 +3690,7 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) dst_sign = H5Tget_sign(dst); buf = aligned_malloc(nelmts*MAX(src_size, dst_size)); saved = aligned_malloc(nelmts*MAX(src_size, dst_size)); - aligned = HDmalloc(sizeof(long_long)); + aligned = HDmalloc(sizeof(long long)); #ifdef SHOW_OVERFLOWS noverflows_g = 0; #endif @@ -3759,12 +3758,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_char = (char)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_char = (char)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_char = (char)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_char = (char)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_char = (char)(*((unsigned long long*)aligned)); break; default: break; @@ -3805,12 +3804,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_uchar = (unsigned char)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_uchar = (unsigned char)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_uchar = (unsigned char)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_uchar = (unsigned char)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_uchar = (unsigned char)(*((unsigned long long*)aligned)); break; default: break; @@ -3851,12 +3850,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_short = (short)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_short = (short)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_short = (short)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_short = (short)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_short = (short)(*((unsigned long long*)aligned)); break; default: @@ -3898,12 +3897,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_ushort = (unsigned short)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_ushort = (unsigned short)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_ushort = (unsigned short)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_ushort = (unsigned short)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_ushort = (unsigned short)(*((unsigned long long*)aligned)); break; default: break; @@ -3944,12 +3943,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_int = (int)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_int = (int)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_int = (int)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_int = (int)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_int = (int)(*((unsigned long long*)aligned)); break; default: break; @@ -3990,12 +3989,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_uint = (unsigned int)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_uint = (unsigned int)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_uint = (unsigned int)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_uint = (unsigned int)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_uint = (unsigned int)(*((unsigned long long*)aligned)); break; default: break; @@ -4036,12 +4035,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_long = (long int)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_long = (long int)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_long = (long int)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_long = (long int)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_long = (long int)(*((unsigned long long*)aligned)); break; default: break; @@ -4082,12 +4081,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) hw_ulong = (unsigned long)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_ulong = (unsigned long)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_ulong = (unsigned long)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_ulong = (unsigned long)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_ulong = (unsigned long)(*((unsigned long long*)aligned)); break; default: break; @@ -4097,43 +4096,43 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) switch (src_type) { case INT_SCHAR: HDmemcpy(aligned, saved+j*sizeof(char), sizeof(char)); - hw_llong = (long_long)(*((char*)aligned)); + hw_llong = (long long)(*((char*)aligned)); break; case INT_UCHAR: HDmemcpy(aligned, saved+j*sizeof(unsigned char), sizeof(unsigned char)); - hw_llong = (long_long)(*((unsigned char*)aligned)); + hw_llong = (long long)(*((unsigned char*)aligned)); break; case INT_SHORT: HDmemcpy(aligned, saved+j*sizeof(short), sizeof(short)); - hw_llong = (long_long)(*((short*)aligned)); + hw_llong = (long long)(*((short*)aligned)); break; case INT_USHORT: HDmemcpy(aligned, saved+j*sizeof(unsigned short), sizeof(unsigned short)); - hw_llong = (long_long)(*((unsigned short*)aligned)); + hw_llong = (long long)(*((unsigned short*)aligned)); break; case INT_INT: HDmemcpy(aligned, saved+j*sizeof(int), sizeof(int)); - hw_llong = (long_long)(*((int*)aligned)); + hw_llong = (long long)(*((int*)aligned)); break; case INT_UINT: HDmemcpy(aligned, saved+j*sizeof(unsigned), sizeof(unsigned)); - hw_llong = (long_long)(*((unsigned*)aligned)); + hw_llong = (long long)(*((unsigned*)aligned)); break; case INT_LONG: HDmemcpy(aligned, saved+j*sizeof(long), sizeof(long)); - hw_llong = (long_long)(*((long*)aligned)); + hw_llong = (long long)(*((long*)aligned)); break; case INT_ULONG: HDmemcpy(aligned, saved+j*sizeof(unsigned long), sizeof(unsigned long)); - hw_llong = (long_long)(*((unsigned long*)aligned)); + hw_llong = (long long)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_llong = (long_long)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_llong = (long long)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_llong = (long_long)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_llong = (long long)(*((unsigned long long*)aligned)); break; default: break; @@ -4143,43 +4142,43 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) switch (src_type) { case INT_SCHAR: HDmemcpy(aligned, saved+j*sizeof(char), sizeof(char)); - hw_ullong = (unsigned long_long)(*((char*)aligned)); + hw_ullong = (unsigned long long)(*((char*)aligned)); break; case INT_UCHAR: HDmemcpy(aligned, saved+j*sizeof(unsigned char), sizeof(unsigned char)); - hw_ullong = (unsigned long_long)(*((unsigned char*)aligned)); + hw_ullong = (unsigned long long)(*((unsigned char*)aligned)); break; case INT_SHORT: HDmemcpy(aligned, saved+j*sizeof(short), sizeof(short)); - hw_ullong = (unsigned long_long)(*((short*)aligned)); + hw_ullong = (unsigned long long)(*((short*)aligned)); break; case INT_USHORT: HDmemcpy(aligned, saved+j*sizeof(unsigned short), sizeof(unsigned short)); - hw_ullong = (unsigned long_long)(*((unsigned short*)aligned)); + hw_ullong = (unsigned long long)(*((unsigned short*)aligned)); break; case INT_INT: HDmemcpy(aligned, saved+j*sizeof(int), sizeof(int)); - hw_ullong = (unsigned long_long)(*((int*)aligned)); + hw_ullong = (unsigned long long)(*((int*)aligned)); break; case INT_UINT: HDmemcpy(aligned, saved+j*sizeof(unsigned), sizeof(unsigned)); - hw_ullong = (unsigned long_long)(*((unsigned*)aligned)); + hw_ullong = (unsigned long long)(*((unsigned*)aligned)); break; case INT_LONG: HDmemcpy(aligned, saved+j*sizeof(long), sizeof(long)); - hw_ullong = (unsigned long_long)(*((long*)aligned)); + hw_ullong = (unsigned long long)(*((long*)aligned)); break; case INT_ULONG: HDmemcpy(aligned, saved+j*sizeof(unsigned long), sizeof(unsigned long)); - hw_ullong = (unsigned long_long)(*((unsigned long*)aligned)); + hw_ullong = (unsigned long long)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_ullong = (unsigned long_long)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_ullong = (unsigned long long)(*((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_ullong = (unsigned long_long)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_ullong = (unsigned long long)(*((unsigned long long*)aligned)); break; default: break; @@ -4348,12 +4347,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) printf(" %29lu\n", *((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long long*)aligned)); break; default: break; @@ -4397,12 +4396,12 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) printf(" %29lu\n", *((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, buf+j*sizeof(long_long), sizeof(long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long_long*)aligned)); + HDmemcpy(aligned, buf+j*sizeof(long long), sizeof(long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, buf+j*sizeof(long_long), sizeof(unsigned long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)aligned)); + HDmemcpy(aligned, buf+j*sizeof(long long), sizeof(unsigned long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long long*)aligned)); break; default: break; @@ -4438,10 +4437,10 @@ test_conv_int_1(const char *name, hid_t src, hid_t dst) printf(" %29lu\n", *((unsigned long*)hw)); break; case INT_LLONG: - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long_long*)hw)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long long*)hw)); break; case INT_ULLONG: - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)hw)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long long*)hw)); break; default: break; @@ -4587,7 +4586,7 @@ my_isnan(dtype_t type, void *val) } else if (FLT_LDOUBLE==type) { long double x; HDmemcpy(&x, val, sizeof(long double)); - sprintf(s, "%Lg", x); + sprintf(s, "%LLg", x); #endif } else { return 0; @@ -5136,7 +5135,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) void *user_data; /*returned pointer to user data passed in to the callback*/ hbool_t except_set = FALSE; /*whether user's exception handling is set*/ const size_t ntests=NTESTS; /*number of tests */ - const size_t nelmts=NTESTELEM; /*num values per test */ + size_t nelmts; /*num values per test */ const size_t max_fails=40; /*max number of failures*/ size_t fails_all_tests=0; /*number of failures */ size_t fails_this_test; /*fails for this test */ @@ -5156,19 +5155,19 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) size_t src_nbits; /*source length in bits */ size_t dst_nbits; /*dst length in bits */ void *aligned=NULL; /*aligned temp buffer */ - float hw_float; - double hw_double; - long double hw_ldouble; - signed char hw_schar; - unsigned char hw_uchar; - short hw_short; - unsigned short hw_ushort; - int hw_int; - unsigned hw_uint; - long hw_long; - unsigned long hw_ulong; - long_long hw_llong; - unsigned long_long hw_ullong; + float hw_float=0; + double hw_double=0; + long double hw_ldouble=0; + signed char hw_schar=0; + unsigned char hw_uchar=0; + short hw_short=0; + unsigned short hw_ushort=0; + int hw_int=0; + unsigned hw_uint=0; + long hw_long=0; + unsigned long hw_ulong=0; + long long hw_llong=0; + unsigned long long hw_ullong=0; /* What is the name of the source type */ if (H5Tequal(src, H5T_NATIVE_SCHAR)) { @@ -5299,7 +5298,15 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) HDputs(" 2. Not a float-integer conversion."); goto error; } - + + /* Reduce the number of elements if the source is "long double" + * because it takes too long. + */ + if(src_type == FLT_LDOUBLE) + nelmts = NTESTELEM / 10; + else + nelmts = NTESTELEM; + /* Allocate buffers */ endian = H5Tget_order(H5T_NATIVE_INT); src_size = H5Tget_size(src); @@ -5308,7 +5315,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) dst_nbits = H5Tget_precision(dst); /* not 8*dst_size, esp on J90 - QAK */ buf = aligned_malloc(nelmts*MAX(src_size, dst_size)); saved = aligned_malloc(nelmts*MAX(src_size, dst_size)); - aligned = HDmalloc(sizeof(long_long)); + aligned = HDmalloc(MAX(sizeof(long double), sizeof(long long))); #ifdef SHOW_OVERFLOWS noverflows_g = 0; #endif @@ -5405,13 +5412,13 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) hw_float = (float)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_float = (float)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_float = (float)(*((long long*)aligned)); break; #ifdef H5_ULLONG_TO_FP_CAST_WORKS case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_float = (float)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_float = (float)(*((unsigned long long*)aligned)); break; #endif /* H5_ULLONG_TO_FP_CAST_WORKS */ default: @@ -5453,13 +5460,13 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) hw_double = (double)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_double = (double)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_double = (double)(*((long long*)aligned)); break; #ifdef H5_ULLONG_TO_FP_CAST_WORKS case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_double = (double)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_double = (double)(*((unsigned long long*)aligned)); break; #endif /* H5_ULLONG_TO_FP_CAST_WORKS */ default: @@ -5501,13 +5508,13 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) hw_ldouble = (long double)(*((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - hw_ldouble = (long double)(*((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + hw_ldouble = (long double)(*((long long*)aligned)); break; #ifdef H5_ULLONG_TO_FP_CAST_WORKS case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - hw_ldouble = (long double)(*((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + hw_ldouble = (long double)(*((unsigned long long*)aligned)); break; #endif /* H5_ULLONG_TO_FP_CAST_WORKS */ default: @@ -5662,15 +5669,15 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) switch (src_type) { case FLT_FLOAT: HDmemcpy(aligned, saved+j*sizeof(float), sizeof(float)); - hw_llong = (long_long)(*((float*)aligned)); + hw_llong = (long long)(*((float*)aligned)); break; case FLT_DOUBLE: HDmemcpy(aligned, saved+j*sizeof(double), sizeof(double)); - hw_llong = (long_long)(*((double*)aligned)); + hw_llong = (long long)(*((double*)aligned)); break; case FLT_LDOUBLE: - HDmemcpy(aligned, saved+j*sizeof(long double), sizeof(double)); - hw_llong = (long_long)(*((long double*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long double), sizeof(long double)); + hw_llong = (long long)(*((long double*)aligned)); break; default: break; @@ -5680,15 +5687,15 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) switch (src_type) { case FLT_FLOAT: HDmemcpy(aligned, saved+j*sizeof(float), sizeof(float)); - hw_ullong = (unsigned long_long)(*((float*)aligned)); + hw_ullong = (unsigned long long)(*((float*)aligned)); break; case FLT_DOUBLE: HDmemcpy(aligned, saved+j*sizeof(double), sizeof(double)); - hw_ullong = (unsigned long_long)(*((double*)aligned)); + hw_ullong = (unsigned long long)(*((double*)aligned)); break; case FLT_LDOUBLE: - HDmemcpy(aligned, saved+j*sizeof(long double), sizeof(double)); - hw_ullong = (unsigned long_long)(*((long double*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long double), sizeof(long double)); + hw_ullong = (unsigned long long)(*((long double*)aligned)); break; default: break; @@ -5730,7 +5737,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) && (INT_SCHAR==dst_type || INT_SHORT==dst_type || INT_INT==dst_type || INT_LONG==dst_type || INT_LLONG==dst_type)) { if(0==H5T_bit_get_d(src_bits, src_nbits-1, 1) && - overflows(src_bits, src_type, src_size, dst_nbits-1)) { + overflows(src_bits, src, dst_nbits-1)) { /* * Source is positive and the magnitude is too large for * the destination. The destination should be set to the @@ -5746,7 +5753,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) continue; /*no error*/ } } else if (1==H5T_bit_get_d(src_bits, src_nbits-1, 1) && - overflows(src_bits, src_type, src_size, dst_nbits-1)) { + overflows(src_bits, src, dst_nbits-1)) { /* * Source is negative but the magnitude is too large for * the destination. The destination should be set to the @@ -5779,7 +5786,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) if (dst_bits[0] == fill_value) continue; /*no error*/ } - } else if (overflows(src_bits, src_type, src_size, dst_nbits)) { + } else if (overflows(src_bits, src, dst_nbits)) { /* * The source is a value with a magnitude too large for * the destination. The destination should be the @@ -5815,10 +5822,10 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) if((tmp_s+1)==tmp_h || (tmp_s-1)==tmp_h) continue; /*no error*/ } /* end if */ - else if (dst_size==sizeof(unsigned long_long)) { - unsigned long_long tmp_s, tmp_h; - HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned long_long)); - HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned long_long)); + else if (dst_size==sizeof(unsigned long long)) { + unsigned long long tmp_s, tmp_h; + HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned long long)); + HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned long long)); if((tmp_s+1)==tmp_h || (tmp_s-1)==tmp_h) continue; /*no error*/ } /* end if */ @@ -5830,9 +5837,9 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) */ #ifndef H5_FP_TO_ULLONG_BOTTOM_BIT_WORKS if((src_type==FLT_FLOAT || src_type==FLT_DOUBLE) && dst_type==INT_ULLONG) { - unsigned long_long tmp_s, tmp_h; - HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned long_long)); - HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned long_long)); + unsigned long long tmp_s, tmp_h; + HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned long long)); + HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned long long)); if((tmp_s+1)==tmp_h) continue; /*no error*/ } @@ -5881,12 +5888,12 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) printf(" %29lu\n", *((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, saved+j*sizeof(long_long), sizeof(long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(long long), sizeof(long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, saved+j*sizeof(unsigned long_long), sizeof(unsigned long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)aligned)); + HDmemcpy(aligned, saved+j*sizeof(unsigned long long), sizeof(unsigned long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long long*)aligned)); break; case FLT_FLOAT: HDmemcpy(aligned, saved+j*sizeof(float), sizeof(float)); @@ -5942,12 +5949,12 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) printf(" %29lu\n", *((unsigned long*)aligned)); break; case INT_LLONG: - HDmemcpy(aligned, buf+j*sizeof(long_long), sizeof(long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long_long*)aligned)); + HDmemcpy(aligned, buf+j*sizeof(long long), sizeof(long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"d\n", *((long long*)aligned)); break; case INT_ULLONG: - HDmemcpy(aligned, buf+j*sizeof(long_long), sizeof(unsigned long_long)); - HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)aligned)); + HDmemcpy(aligned, buf+j*sizeof(unsigned long long), sizeof(unsigned long long)); + HDfprintf(stdout," %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long long*)aligned)); break; case FLT_FLOAT: HDmemcpy(aligned, buf+j*sizeof(float), sizeof(float)); @@ -5995,10 +6002,10 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) printf(" %29lu\n", *((unsigned long*)hw)); break; case INT_LLONG: - printf(" %29"H5_PRINTF_LL_WIDTH"d\n", *((long_long*)hw)); + printf(" %29"H5_PRINTF_LL_WIDTH"d\n", *((long long*)hw)); break; case INT_ULLONG: - printf(" %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long_long*)hw)); + printf(" %29"H5_PRINTF_LL_WIDTH"u\n", *((unsigned long long*)hw)); break; case FLT_FLOAT: printf(" %29f\n", *((float*)hw)); @@ -6064,27 +6071,33 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) *------------------------------------------------------------------------- */ static hbool_t -overflows(unsigned char *origin_bits, dtype_t src_dtype, size_t src_size_bytes, size_t dst_num_bits) +overflows(unsigned char *origin_bits, hid_t src_id, size_t dst_num_bits) { hbool_t ret_value=FALSE; hsize_t expt, sig; - size_t frct_digits=0, expt_digits=0, bias=0; + size_t mant_digits=0, expt_digits=0, bias=0; + size_t src_prec=0; /*source type precision in bits*/ + H5T_norm_t norm; ssize_t indx; - unsigned char bits[32]; + unsigned char bits[32], mant_bits[32]; - HDmemcpy(bits, origin_bits, src_size_bytes); + HDmemset(bits, 0, 32); + HDmemset(mant_bits, 0, 32); + + /* + * Sometimes, type size isn't equal to the precision like Linux's "long + * double", where size is 96 bits and precision is 80 bits. + */ + + src_prec = H5Tget_precision(src_id); + H5Tget_fields(src_id, NULL, NULL, &expt_digits, NULL, &mant_digits); + bias = H5Tget_ebias(src_id); + norm = H5Tget_norm(src_id); + + HDmemcpy(bits, origin_bits, src_prec/8+1); - if(src_dtype==FLT_FLOAT) { - frct_digits = (FLT_MANT_DIG-1); - expt_digits = (sizeof(float)*8)-(frct_digits+1); - } else if(src_dtype==FLT_DOUBLE) { - frct_digits = (DBL_MANT_DIG-1); - expt_digits = (sizeof(double)*8)-(frct_digits+1); - } - bias = (1<<(expt_digits-2)) - 1; - /* get exponent */ - expt = H5T_bit_get_d(bits, frct_digits, expt_digits) - bias; + expt = H5T_bit_get_d(bits, mant_digits, expt_digits) - bias; if(expt>=(dst_num_bits-1)) { ret_value=TRUE; @@ -6092,18 +6105,19 @@ overflows(unsigned char *origin_bits, dtype_t src_dtype, size_t src_size_bytes, } /* get significand */ - sig = H5T_bit_get_d(bits, 0, frct_digits); + H5T_bit_copy (mant_bits, 0, bits, 0, mant_digits); + - /* restore implicit bit*/ - sig |= (hsize_t)1<<frct_digits; + /* restore implicit bit if normalization is implied*/ + if(norm == H5T_NORM_IMPLIED) { + H5T_bit_inc(mant_bits, mant_digits, 1); + mant_digits++; + } /* shift significand */ - if(expt>expt_digits) - sig <<= expt - expt_digits; - else - sig >>= expt_digits - expt; + H5T_bit_shift (mant_bits, (expt-expt_digits), 0, 32*8); - indx = H5T_bit_find((uint8_t *)&sig, 0, 8*sizeof(hsize_t), H5T_BIT_MSB, 1); + indx = H5T_bit_find(mant_bits, 0, 32*8, H5T_BIT_MSB, 1); if((size_t)indx>=dst_num_bits) ret_value=TRUE; @@ -6347,6 +6361,49 @@ run_int_float_conv(const char *name) #endif /* H5_ULLONG_TO_FP_CAST_WORKS */ #endif + if(!strcmp(name, "sw")) { +#if H5_SW_LDOUBLE_TO_INT_WORKS +#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE + nerrors += test_conv_int_float(name, H5T_NATIVE_SCHAR, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_int_float(name, H5T_NATIVE_UCHAR, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_int_float(name, H5T_NATIVE_SHORT, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_int_float(name, H5T_NATIVE_USHORT, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_int_float(name, H5T_NATIVE_INT, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_int_float(name, H5T_NATIVE_UINT, H5T_NATIVE_LDOUBLE); +#if H5_SIZEOF_LONG!=H5_SIZEOF_INT + nerrors += test_conv_int_float(name, H5T_NATIVE_LONG, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_int_float(name, H5T_NATIVE_ULONG, H5T_NATIVE_LDOUBLE); +#endif +#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 + nerrors += test_conv_int_float(name, H5T_NATIVE_ULLONG, H5T_NATIVE_LDOUBLE); +#else /* H5_ULLONG_TO_FP_CAST_WORKS */ + { + char str[256]; /*hello string */ + + sprintf(str, "Testing random %s %s -> %s conversions", + name, "unsigned long long", "long double"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to compiler not handling conversion."); + } +#endif /* H5_ULLONG_TO_FP_CAST_WORKS */ +#endif +#endif +#else /*H5_SW_LDOUBLE_TO_INT_WORKS*/ + { + char str[256]; /*string */ + + sprintf(str, "Testing random %s %s -> %s conversions", + name, "all integers", "long double"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } +#endif /*H5_SW_LDOUBLE_TO_INT_WORKS*/ + } + return nerrors; } @@ -6420,7 +6477,51 @@ run_float_int_conv(const char *name) } #endif /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ #endif - + + if(!strcmp(name, "sw")) { +#if H5_SW_LDOUBLE_TO_INT_WORKS +#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SCHAR); + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UCHAR); + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SHORT); + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_USHORT); + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_INT); + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UINT); +#if H5_SIZEOF_LONG!=H5_SIZEOF_INT + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULONG); +#endif + +#if H5_SIZEOF_LONG_LONG!=H5_SIZEOF_LONG + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LLONG); +#ifdef H5_FP_TO_ULLONG_RIGHT_MAXIMUM + nerrors += test_conv_int_float(name, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULLONG); +#else /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ + { + char str[256]; /*string */ + + sprintf(str, "Testing random %s %s -> %s conversions", + name, "long double", "unsigned long long"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } +#endif /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ +#endif +#endif +#else /*H5_SW_LDOUBLE_TO_INT_WORKS*/ + { + char str[256]; /*hello string */ + + sprintf(str, "Testing random %s %s -> %s conversions", + name, "long double", "all integers"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } +#endif /*H5_SW_LDOUBLE_TO_INT_WORKS*/ + } + return nerrors; } |