On Tue, Aug 20, 2013 at 2:58 PM, Tina Harriott <[email protected]> wrote: > On 19 August 2013 23:24, Roland Mainz <[email protected]> wrote: >> On Mon, Aug 19, 2013 at 8:10 PM, David Korn <[email protected]> wrote: [snip] >> On a 2nd thought... maybe we should define these constants via C99 >> hexfloat to make sure the last bits are OK... >> > > What exactly is a C99 hexfloat?
"C99 hexfloat" refers to the ISO C (C99, see http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf) hexadecimal floating point constants. They were invented to deal with the issue that IEEE 754-2008 floating-point values (e.g. the C datatypes |float|, |double|, |long double|) are internally base-2 based while humans usually use base-10. To gurantee that a binary base-2 floating-point variable can be stored as string a hexadecimal notation was added so that a floating-point value can be stored as string and be converted back to the same binary value. ksh93 supports this via the $ typeset -X ... # datatype and the printf "%a" format. Example: The following code shows the difference (in the last bits) between the sum of base10 (3.+0.11+0.11+0.11) and base10 3.33. Human intuitution would assume both values are identical but they are not the same for the computer as youcan see in the output of %a below: -- snip -- $ ksh -c 'float x y ; (( x=3 , x+=0.11 , x+=0.11 , x+=0.11 , y=3.33 )) ; printf "%f %a\n" x x y y' 3.330000 0x1.aa3d70a3d70a3d6e000000000000p+1 3.330000 0x1.aa3d70a3d70a3d70000000000000p+1 -- snip -- Note that printf(1) takes the variable name and not the string values of $x and $y since converting the variables x/y to a string implies a base2--->base10 conversion. If I do that mistake both values are identical because the base2--->base10 conversion happens at $x/$y time... long before printf(1) sees the arguments: -- snip -- $ ksh -c 'float x y ; (( x=3 , x+=0.11 , x+=0.11 , x+=0.11 , y=3.33 )) ; printf "%f %a\n" $x $x $y $y' 3.330000 0x1.aa3d70a3d70a3d70000000000000p+1 3.330000 0x1.aa3d70a3d70a3d70000000000000p+1 -- snip -- ... however if I replace "float" (which is an alias for $ typeset -lE ... #) with "typeset -lX" the values differ again because the implicit base2-->hexfloat conversion is lossless: -- snip -- $ ksh -c 'typeset -lX x y ; (( x=3 , x+=0.11 , x+=0.11 , x+=0.11 , y=3.33 )) ; printf "%f %a\n" $x $x $y $y' 3.330000 0x1.aa3d70a3d70a3d6e000000000000p+1 3.330000 0x1.aa3d70a3d70a3d70000000000000p+1 -- snip -- Or short: Use $ typeset -X ... # and printf "%a" if you wish to store floating-point values accurately... ---- 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
