Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2003-12-11 18:37:44


Guillaume Melquiond wrote:

> [snipped]
>
> Hi,
>
> I just took a quick glance at the documentation for now. I will later
> do
> a better review.

Great! waiting... :-)

> However, there are a few problems with some
> algorithms
> and I wanted to mention it as soon as possible.
>
Good idea!

> 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.
>
Hmmm...
OK, I see the problem....
Seems difficult to deal with without compromising efficiency for the safe
cases (<2^23).
Anyway, it is a problem rather specific of the fixed -known size- floating
point formats (such as the builtin floats), so I figure that I'll only need
to provide custom specialization of the rounder policies for these types.

> 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.

Yes I see... essentially the same problem as before right? I think the
change you suggest is appropriate, thanks!

>
> 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.

Oh, Ok. I'll fix them.

>
> 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.
I can't find what 'later explanation' are you referring to... or I don't see
the error :-)
Can you be more specific?

Anyway, this part of the documentation is intended to be as consistent and
precise as possible, so that is a good place to be pedantic :-)
The more and finer corrections I get the better the result.

> 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.

I never quite understood the difference :-)
So if you can help me out with the right descriptions I'd much appreciate
it.

>
> Finally what is the rational for returning 0 in bounds::smallest when
> it's an integer type?

The decision was rather arbitrary (way too arbitrary :-)
Now after thinking about it I realize that it should be 1, not 0; which is
the proper parallel to the smallest float value (which happens not to be 0)

> And why return the smallest normalized
> floating-point number? Why not the smallest floating-point number?

This is because the ISO98 standard doesn't know about subnormals, so the
smallest value that can be portably represented as far as C++ is concerned
must be normalized.
(this is why numeric_limits<a_float_type>::min() returns a normalized
number)

> Or even better the two of them?

Because subnormals don't legally exist in C++.

> And what about ulp(1) or the smallest
> floating-point number following 1?
>
This is way too big, isn't it?
smallest() substitutes numeric_limits<a_float_type>::min().

Thanks for your mini-review....
I'm looking forward for a full review from you!

Best regards,

Fernando Cacciola
SciSoft


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