Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2008-06-19 09:40:46


Thanks for doing this Darren. A few comments below...

On Jun 18, 2008, at 11:48 PM, Darren Garvey wrote:
> I thought this bit looked simple enough to have a go at, so I took a
> shot at
> it and am attaching the results (tested with gcc 4.2.3 on Ubuntu). My
> conclusion is that the (relevant bit of) text is as clear as it
> needs to be
> - since I could follow it - except for one point:
>
> When it says:
> """
> num shall have the value sign(N)*sign(D)*abs(N)/gcd.
>
> den shall have the value abs(D)/gcd.
>
> """
>
> ... are sign() and abs() supposed to be runtime functions? I
> implemented
> them as meta-functions - I'm sure these are in boost somewhere, I
> just don't
> know where. Maybe compilers are generally clever enough, or the
> standard
> guarantees those functions will be evaluated at compile time? I'm
> never sure
> where the line is drawn on this one...

They have to execute at compile time. Whether or not the C++0X
constexpr feature can be brought to bear here I really don't know. In
my example implementation they were simply "__"-prefixed meta functions.

> The attached code is quite straightforward and basically does what
> the text
> says it should (I hope), but no more. The main limitation is that it
> uses
> static_gcd<> from Boost.Math. That meta-function is parametrised with
> `unsigned long` instead of `intmax_t` which limits how big the allowed
> numbers can be. I tried without luck to change the relevant header
> but I
> suppose it's not really relevant to this experiment.

This is a show-stopper. One of the basic features of ratio is that
you can throw any integral value at it, and it will either hand back
the right answer or refuse to compile.

Some worrisome results:

     typedef boost::utility::ratio<1, 0x8000000000000000LL> R9;
     std::cout << R9::num << '/' << R9::den << '\n';

-1/-9223372036854775808

This paragraph:

> A diagnostic shall be emitted if ratio is instantiated with D == 0,
> or if the absolute value of N or D can not be represented. [Note:
> These rules ensure that infinite ratios are avoided and that for any
> negative input, there exists a representable value of its absolute
> value which is positive. In a two's complement representation, this
> excludes the most negative value. -- end note]

was intended to cause the above example to fail to compile because
abs(0x8000000000000000) < 0.

Once we have an intmax_t-based gcd, the ratio arithmetic and less-than
comparison will need more work to detect overflow and subsequently
refuse to compile:

> For each of the class templates in this clause, each template
> parameter shall refer to a ratio. If the implementation is unable to
> form the indicatedratio due to overflow, a diagnostic shall be issued.

...

> If R1::num * R2::den < R2::num * R1::den, ratio_less derives from
> true_type, else derives from false_type. Implementations are
> permitted to use more complex algorithms to compute the above
> relationship to avoid overflow. If the implementation is not able to
> avoid overflow, a diagnostic shall be emitted.

In general, N2615 is sprinkled liberally with "diagnostic required".
Errors which can be detected at compile time are actively sought out.

-Howard


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