Email List: Xaustin-review-lX
[All Lists]

Re: Defect in XSH exp

To: yyyyyyyyyyyyyyy@xxxxxxxxxxxxx
Subject: Re: Defect in XSH exp
From: Loic Domaigne <yyyyyyyy@xxxxxxx>
Date: Thu, 17 Jul 2003 20:29:52 +0200 (MEST)
References: <20030717163408.GZ83371@finch-staff-1.thus.net>
Hi Clive, 

many thanks for your information. 


[Clive wrote:] 

> Firstly, annex F does not apply to all implementations - it's an 
> optional extra. 

Oh... I didn't know that it was an optional feature :(
From a numerical analyst point of view, I guess this feature 
makes definitively sense... 


> Secondly, the requirements on conversion of constants are, um,
> complicated (they took an awful lot of discussion time in WG14 
> meetings).
> Putting a constant like that is not sufficient. At the very 
> least, if IEEE754 applies, you should be using a hex constant not 
> a decimal one.

Now I understand why the internal functions of libm uses hex 
constants to e.g. compare values... 


> C99 6.4.4.2:
>  [#3] [...]
>       For  decimal  floating  constants,  and also for hexadecimal
>       floating constants when FLT_RADIX is not a power of  2,  the
>       result  is  either  the  nearest representable value, or the
>       larger or smaller representable value  immediately  adjacent
>       to   the   nearest   representable   value,   chosen  in  an
>       implementation-defined  manner.   For  hexadecimal  floating
>       constants  when  FLT_RADIX  is  a  power of 2, the result is
>       correctly rounded.

The formalism looks complicated, but it is quite simple in reality. 
This § just says that if a number can't be exactly represented in 
base 2 (the natural base of a computer), the rounding is up to the 
implementation. 

An illustration using the human base "10": 

How is represented the constant 2.0/3, assuming that the 
representation allows 5 places? 

2.0/3 = 0.66666666...

This § says that the convertion will be either 0.66666 or 0.66667,
and that the outcome is implementation specific. 

The only difference between this simple example and this §
is that computer uses base 2, not 10. But the principle is the same.
So you can easily deduce that the "last bit" might differ between 
2 ISO C99 representation, even if IEEE754 is used. 

That's at least my understanding... 


An interesting point here: in <math.h> the constants M_E,
M_PI etc. are sometimes #define'd in decimal, even on a C99 
implementation using IEEE754:

# define M_E            2.7182818284590452354   /* e */
# define M_LOG2E        1.4426950408889634074   /* log_2 e */
# define M_LOG10E       0.43429448190325182765  /* log_10 e */
[...] 

This would means that such a <math.h> is deficient!!! Should we 
submit an ardvaark on this issue??? 


> > I guess, you have understand the problem here. The fact is that 
> > the coefficient is a constant (in the C99 sense). However, I can't 
> > initialize it to 1.0 / sqrt (2 * M_PI), because the compiler will 
> > issue something like: 
> > 
> > "error: initializer element is not constant"
> 
> Of course. So my code initializes it on the first call and then uses 
> that value on all subsequent calls.

That was perfectly clear ;-) That's why I said "you have understand 
the problem". 


> > If you don't want to have the value hard-coded, you could declare 
> > the coefficient "c" as: 
> > 
> > const double c = (M_SQRT2 * M_2_SQRTPI) / 4;
> >  
> > Ok, I agree that's hard to recognize the 1.0/sqrt(2*pi), so comments 
> > are definitively needed. 
> 
> Those constants aren't in the C Standard so I can't check them. 

I beg your pardon?? They are are defined in <math.h>, see 
XBD / <math.h> of this SUS. 


Regards, 
Loic.

-- 
+++ GMX - Mail, Messaging & more  http://www.gmx.net +++

Jetzt ein- oder umsteigen und USB-Speicheruhr als Prämie sichern!

<Prev in Thread] Current Thread [Next in Thread>