On Fri, Feb 8, 2013 at 9:35 AM, Lionel Cons
<[email protected]> wrote:
[snip]
> What we're facing here seems that different implementations of a libm
> function may result different results at the last digits, right? Is
> there a function to test how accurate the libm functions are, and is
> there a libm function which tests for equality in a specified
> precision?
Testing whether two _floating_point_-values are equal is a tricky
business (e.g. the C99/ksh93 operator "==" is usually of little use...
;-( ) because of the rounding errors or (AFAIK in your case when the
i387 version of IEEE 754-2008 floating-point values are used) extra
precision caused by the issue that |long double| is 80bit on x86/AMD64
but some machine instructions have extra bits available during
calculation (like the new FMA instructions vs. a "manual"
multiply–accumulate operation... or |pow()| vs. manual "power of" ...)
or the registers have more bits than they store in memory.
Another issue may be (or often is) the base10<---->base2 conversion
which causes rounding errors when strings are converted to IEEE
754-2008 floating-point values and back. As "fix" C99 ([1]) added the
printf "%a" format to represent floating-point values in a hexadecimal
floating-point representation which can be used (with your example) to
"visualise" the issue that the difference is usually off by one or two
bits at the trailing end.
Keeping the email short (due lack of time... I may try a more detailed
answer when I have time) ... the standards only define |isgreater()|,
|isgreaterequal()|, |islessequal()|, |islessgreater()|,
|isunordered()| but intentionally no |isequal()| because the same
operation using different implementations is usually unlikely to
result in _exactly_ the same result.
A quick&&dirty implementation for a |isequal()| (maybe a better term
may be |isnearequal()|) may look like this (ksh93 syntax):
-- snip --
# test whether values in variables "a" and "b" are
# "equal" with a precision of 0.000001
if (( fabs(a - b) < 0.000001 )) ; then
-- snip --
(yes yes... I'm using the wrong mathematical terms (e.g. "precision" ?
"resolution" ? "distance" ?) in this case... please correct me... ;-(
)
[1]=ksh93 supports C99 "hexfloat" via it's printf builtin (note that
you have to use $ float varname ; ... ; printf "%a\n" varname # and
NOT $ float varname ; ... ; printf "%a\n" ${varname} # because the
${varname} means that the internal IEEE 754-2008 floating-point value
is converted to a base10 floating-point string value first and THEN
passed to the printf builtin utility) and via $ typeset -lX varname #
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) [email protected]
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers