diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-11-24 16:49:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-11-24 16:49:27 (GMT) |
commit | 80c45ea54921218b63339fc9460b4f7a1d58c554 (patch) | |
tree | 5df409383fcbaffb81c20b5f6d1d44ae579e91ee /src/H5Tconv.c | |
parent | 7d68090f0362cf562c497e8b4ee730a2ba634215 (diff) | |
download | hdf5-80c45ea54921218b63339fc9460b4f7a1d58c554.zip hdf5-80c45ea54921218b63339fc9460b4f7a1d58c554.tar.gz hdf5-80c45ea54921218b63339fc9460b4f7a1d58c554.tar.bz2 |
[svn-r7876] Purpose:
Omnibus floating-point bug fix changes
Description:
There are a number of problems in the floating-point conversion code that
were exposed by Ray's recent int<->float checkin:
- The 'my_isnan' code in test/dtypes.c was broken and would always return
true. The meant that the actual values in the float<->float conversion
tests were _never_ checked, hiding the other bugs included in this
checkin.
- A recent change I made to the type conversion code used "FLT_MIN" instead
of "-FLT_MAX" for the most negative 'float' value for the double->float
conversion, which meant that any the negative number that was converted
from a double to a float would have been mapped to zero, essentially.
- A change that Robb appeared to have made ~2.5 years ago to the "generic"
float->float conversion routine appears to be incorrect and I've backed
it out.
- Floating-point conversions on SGI's which converted denormalized values
would be mapped to zero instead of being propertly preserved in the new
type. This was addressed by an SGI-specific system call to prevent the
behavior.
Solution:
Described above, generally.
Platforms tested:
FreeBSD 4.9 (sleipnir)
h5committest
Misc. update:
release_docs/RELEASE update forthcoming...
Diffstat (limited to 'src/H5Tconv.c')
-rw-r--r-- | src/H5Tconv.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c index b880d2e..524e8ec 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -299,9 +299,23 @@ H5FL_BLK_DEFINE_STATIC(array_seq); H5T_CONV(H5T_CONV_xX, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ } +/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN + * when an overflow occurs, use the 'float' infinity values. + */ +#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ + if (*((ST*)S) > (DT)(D_MAX)) { \ + if (!H5T_overflow_g || (H5T_overflow_g)(src_id, dst_id, S, D)<0) \ + *((DT*)D) = (H5T_NATIVE_FLOAT_POS_INF_g); \ + } else if (*((ST*)S) < (D_MIN)) { \ + if (!H5T_overflow_g || (H5T_overflow_g)(src_id, dst_id, S, D)<0) \ + *((DT*)D) = (H5T_NATIVE_FLOAT_NEG_INF_g); \ + } else \ + *((DT*)D) = (DT)(*((ST*)S)); \ +} + #define H5T_CONV_Ff(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \ assert(sizeof(ST)>=sizeof(DT)); \ - H5T_CONV(H5T_CONV_Xx, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ + H5T_CONV(H5T_CONV_Ff, double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \ } /* The main part of every integer hardware conversion macro */ @@ -3304,6 +3318,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, } /* Write the exponent */ +#ifdef OLD_WAY +/* It appears to be incorrect to increment the exponent when the carry is set -QAK */ if (carry) { expo++; if (expo>=expo_max) { @@ -3332,6 +3348,7 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); } } +#endif /* OLD_WAY */ H5_CHECK_OVERFLOW(expo,hssize_t,hsize_t); H5T_bit_set_d(d, dst.u.f.epos, dst.u.f.esize, (hsize_t)expo); @@ -6627,7 +6644,7 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, FUNC_ENTER_NOAPI(H5T_conv_float_double, FAIL); - H5T_CONV_Ff(DOUBLE, FLOAT, double, float, FLT_MIN, FLT_MAX); + H5T_CONV_Ff(DOUBLE, FLOAT, double, float, -FLT_MAX, FLT_MAX); done: FUNC_LEAVE_NOAPI(ret_value); |