Difference between revisions of "Ieee arithmetic"

(New page: =Introduction= We will present some of the trade-offs for computation of IEEE arithmetic for REAL_64 and REAL_32 as implemented in EiffelStudio where NaN is not an unordered value but a va...)
 
Line 1: Line 1:
=Introduction=
+
We will present some of the trade-offs for computation of IEEE arithmetic for REAL_64 and REAL_32 as implemented in EiffelStudio where NaN is not an unordered value but a value less than all the other values (note that in some other frameworks, we have seen it defined as the largest value). On other words:
We will present some of the trade-offs for computation of IEEE arithmetic for REAL_64 and REAL_32 as implemented in EiffelStudio where NaN is not an unordered value but a value less than all the other values (note that in some other frameworks, we have seen it defined as the largest value).
+
* NaN = NaN yields True
 +
* NaN < x for all x but NaN
 +
 
 +
To best show the trade-offs we will start by showing some benchmark results.
  
 
=Benchmarks=
 
=Benchmarks=
 +
 +
==The code==
 +
 +
<c>
 +
static EIF_NATURAL_64 to_raw_bits (EIF_REAL_64 d) {
 +
return *((EIF_NATURAL_64 *)&d);
 +
}
 +
 +
static int eif_is_nan_bits (EIF_NATURAL_64 value) {
 +
/* Clear the sign mark. */
 +
    EIF_NATURAL_64 jvalue = (value & ~RTU64C(0x8000000000000000));
 +
/* Ensure that it starts with 0x7ff and that the mantissa is not 0. */
 +
    return (jvalue > RTU64C(0x7ff0000000000000));
 +
}
 +
 +
static int eif_is_nan (EIF_REAL_64 value) {
 +
return eif_is_nan_bits(to_raw_bits (value));
 +
}
 +
 +
static int eif_equal_real_64 (EIF_REAL_64 d1, EIF_REAL_64 d2) {
 +
#ifdef METH1
 +
/* Here the base comparison is IEEE arithmetic. */
 +
return (d1 == d2);
 +
#elif defined(METH2)
 +
/* Conversion to perform comparison on the binary representation. */
 +
EIF_NATURAL_64 f1 = to_raw_bits(d1);
 +
EIF_NATURAL_64 f2 = to_raw_bits(d2);
 +
return (f1 == f2 ? 1 : (eif_is_nan_bits (f1) ? eif_is_nan_bits(f2) : 0));
 +
#elif defined(METH3)
 +
/* Use IEEE arithmetic to compare and find out if we have NaNs. */
 +
return (d1 == d2 ? 1 : ((d1 != d1) && (d2 != d2)));
 +
#elif defined (METH4)
 +
/* Pessimist case, we assume that we compare mostly NaNs. */
 +
return (d1 == d1 ? d1 == d2 : d2 != d2);
 +
#elif defined(METH5)
 +
/* Use IEEE arithmetic to compare but use binary representation to
 +
* find out if we have NaNs. */
 +
return (d1 == d2 ? 1 : (eif_is_nan (d1) && eif_is_nan(d2)));
 +
#endif
 +
}
 +
</c>
  
 
==Testing for NaN values==
 
==Testing for NaN values==

Revision as of 10:12, 2 February 2010

We will present some of the trade-offs for computation of IEEE arithmetic for REAL_64 and REAL_32 as implemented in EiffelStudio where NaN is not an unordered value but a value less than all the other values (note that in some other frameworks, we have seen it defined as the largest value). On other words:

  • NaN = NaN yields True
  • NaN < x for all x but NaN

To best show the trade-offs we will start by showing some benchmark results.

Benchmarks

The code

static EIF_NATURAL_64 to_raw_bits (EIF_REAL_64 d) {
	return *((EIF_NATURAL_64 *)&d);
}
 
static int eif_is_nan_bits (EIF_NATURAL_64 value) {
		/* Clear the sign mark. */
    EIF_NATURAL_64 jvalue = (value & ~RTU64C(0x8000000000000000));
		/* Ensure that it starts with 0x7ff and that the mantissa is not 0. */
    return (jvalue > RTU64C(0x7ff0000000000000));
}
 
static int eif_is_nan (EIF_REAL_64 value) {
	return eif_is_nan_bits(to_raw_bits (value));
}
 
static int eif_equal_real_64 (EIF_REAL_64 d1, EIF_REAL_64 d2) {
#ifdef METH1
		/* Here the base comparison is IEEE arithmetic. */
	return (d1 == d2);
#elif defined(METH2)
		/* Conversion to perform comparison on the binary representation. */
	EIF_NATURAL_64 f1 = to_raw_bits(d1);
	EIF_NATURAL_64 f2 = to_raw_bits(d2);
	return (f1 == f2 ? 1 : (eif_is_nan_bits (f1) ? eif_is_nan_bits(f2) : 0));
#elif defined(METH3)
		/* Use IEEE arithmetic to compare and find out if we have NaNs. */
	return (d1 == d2 ? 1 : ((d1 != d1) && (d2 != d2)));
#elif defined (METH4)
		/* Pessimist case, we assume that we compare mostly NaNs. */
	return (d1 == d1 ? d1 == d2 : d2 != d2);
#elif defined(METH5)
		/* Use IEEE arithmetic to compare but use binary representation to
		 * find out if we have NaNs. */
	return (d1 == d2 ? 1 : (eif_is_nan (d1) && eif_is_nan(d2)));
#endif
}

Testing for NaN values