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: | ||
− | + | 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 09: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 }