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

Reply via email to