Boost logo

Boost :

From: Guillaume Melquiond (guillaume.melquiond_at_[hidden])
Date: 2003-12-11 12:05:05


Le mar 09/12/2003 à 20:59, Fernando Cacciola a écrit :
> > Here is a link:
> >
> > http://groups.yahoo.com/group/boost/files/numeric_conversions.zip
> >
> Since there seems to be some sort of problem with the Files section, I've
> uploaded it here:
>
> http://personales.ciudad.com.ar/fernando_cacciola/numeric_conversions.zip
>
> Fernando Cacciola
> SciSoft

Hi,

I just took a quick glance at the documentation for now. I will later do
a better review. However, there are a few problems with some algorithms
and I wanted to mention it as soon as possible.

When doing float to int conversion, you use this formula: floor(f + 0.5)
Unfortunately, the formula won't work for some conversions. Here is a
small snippet of a C program (the "volatile" keyword is used all over
the place so that you can test it on x86 and PPC).

#include <math.h>
#include <stdio.h>
#include <assert.h>
int main() {
  int a = (1 << 24) - 1;
  volatile float b = a;
  volatile float c = b + 0.5f;
  volatile float d = floorf(c);
  int e = d;
  assert((double)a == (double)b);
  printf("%d %d\n", a, e);
  return 0;
}

The integer is the biggest odd integer representable as simple precision
floating-point number. So the conversion from float to int should not
modify the value (since it already is an integer). However, as you can
see, the final value is different from the first value. The same will
happen with any odd integer between 2^23 and 2^24 (and their negative
counterpart). So it's not a few cases, there is unfortunately a bunch of
them.

Another problem with rounding to nearest (that's because it's a rounding
to "even"). This range may be too big: ( s >= S(LowestT)-S(0.5) ) && ( s
<= S(HighestT)+S(0.5) ). It's probably better if it's only < for the
positive part because the biggest positive number of an integer type is
usually odd.

Concerning the documentation, there are a few places where the < and >
are badly written. By rgrep-ing with '[^&][lg]t;' and '&[lg]t[^;]' you
should find all the occurrences.

In the definition part of the documentation, the notions of "range" of a
type and "overflow" don't match the later explanation of float to int
rounding. You should also be a bit more cautious when speaking of
"correct rounding". Sometimes what you describe is only a "faithful
rounding" (a faithful rounding becomes correct only when the direction
of rounding is precisely known). But I'm splitting hairs.

Finally what is the rational for returning 0 in bounds::smallest when
it's an integer type? And why return the smallest normalized
floating-point number? Why not the smallest floating-point number? Or
even better the two of them? And what about ulp(1) or the smallest
floating-point number following 1?

Regards,

Guillaume


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