Boost logo

Boost :

From: Sylvain Pion (pion_at_[hidden])
Date: 2002-09-04 19:39:10


On Thu, Sep 05, 2002 at 01:55:39AM +0200, Gabriel Dos Reis wrote:
> Sylvain Pion <pion_at_[hidden]> writes:
>
> | Hence all the compilers you have tested might define this to be the
> | rounding to nearest, but we can't theoretically rely on it :(
>
> Then, probably you might want to consult numeric_limits<>::round_style.

Thanks for pointing this out, I had missed it.
But the fact remains that I have to do something in the case it's
round_indeterminate, so I fear it doesn't bring me much...

> | Not a big requirement, you'll have to admit.
>
> Really?

Well, as a first start, it's completely reasonnable. I've never touched a
machine where int/float/double didn't match these requirements. Did you ?

But anyway, I completely agree that it's not complete, and I would like to
find a scheme to improve this. You may have some helpful comments on this.

To recall, what I want is the sharpest interval bounds (for float, double,
long double) on PI (other constants might follow, but this one is needed for
the trigonometric functions).

As mentionned above, the standard doesn't impose any particular rounding style,
so you can't assume a particular one, so a decimal FP constant might be rounded
to any of the two closest representable binary FP values enclosing it.
But when it's exactly representable, the standard guarantees that you get the
right value. So I plan to exploit this (well, that's what my original code did
as well somehow), and the fact that any binary FP value fits exactly in a
decimal FP value.

So, if numeric_limits<float>::digits==24 (the usual value), then instead of
my current code :

static const float pi_f_l = 13176794.0f/(1<<22);

I could define it as the same value encoded decimally :

static const float pi_f_l = 3.141592502593994140625f;

I checked on Sparc/Solaris with G++ 3.1.1 and SunPRO and it worked.
Note that it has more digits than necessarily, if you consider the usual
"significant" digits definition.

Now the question is : what do we do when numeric_limits<float>::digits is
different ? Well, I don't have any clean idea I guess. I'd go for :

static const float pi_f_l =
  std::numeric_limits<float>::digits==NN ? some value :
  std::numeric_limits<float>::digits==NN-1 ? some other adequate value :
  std::numeric_limits<float>::digits==... ? another value :
  std::numeric_limits<float>::digits==24 ? 3.141592502593994140625f :
  std::numeric_limits<float>::digits==23 ? another adequate value :
  std::numeric_limits<float>::digits==... ? another value :
  std::numeric_limits<float>::digits==1 ? 2 ;

Something similar can be done for the other constants for double and long
double.

Is there a cleaner way to do that ?

-- 
Sylvain

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk