Boost logo

Boost :

From: Paul Moore (gustav_at_[hidden])
Date: 2000-11-19 16:57:19


From: ebo_at_[hidden] [mailto:ebo_at_[hidden]]
> Description and reproducion:
>
> The devision of a rational by "0" does not throw an exception but
> returns a 0 denominator in the result. If you trace through the
> rational code example you will find that the exception is actually
> never generated by the test code.
>
> Effected code segment:
>
> boost/rational.hpp: 195-206
>
> Proposed Fix:
>
> Add a bad_rational test (denominator == 0) test and throw an
> exception.
>
> template <typename IntType>
> rational<IntType>& rational<IntType>::operator/= (const
> rational<IntType>& r)
> {
> // Avoid overflow and preserve normalization
> IntType gcd1 = gcd<IntType>(num, r.num);
> IntType gcd2 = gcd<IntType>(r.den, den);
> num = (num/gcd1) * (r.den/gcd2);
> den = (den/gcd2) * (r.num/gcd1);
> >>> // validity check
> >>> if (0 == den) throw bad_rational();
> return *this;
> }

Good point. I missed this case. And thanks for the clear and detailed bug
report.

I'd rather add a check as

template <typename IntType>
rational<IntType>& rational<IntType>::operator/= (const rational<IntType>&
r)
{
    // Trap division by zero
    if (r.num == 0) throw bad_rational();
    // Avoid overflow and preserve normalization
    IntType gcd1 = gcd<IntType>(num, r.num);
    IntType gcd2 = gcd<IntType>(r.den, den);
    num = (num/gcd1) * (r.den/gcd2);
    den = (den/gcd2) * (r.num/gcd1);
    return *this;
}

I.e., test at the top, on the pinciple of avoiding unnecessary work. Why
calculate two GCDs when you won't use them?

A question - should this throw bad_rational() or is there a standard divide
by zero exception? (Couldn't find one in a brief glance in the standard...)

Beman, could you add this or would you like me to send a complete
replacement rational.hpp?

> Notes:
>
> as an aside, years ago I learned a little programming trick which I
> used above. By placing the literal on the left hand side of the
> expression I use compilers parser to catch certain types of typos.
> In this way if I inadvertently type a "=" instead of a "==" the
> compiler will see it as a syntax error. i.e. a "if (0=den)"
> produces a syntax error where as "if (den=0)" is valid but not what
> I wanted. Just an aside...

I've seen this before, and the rationale is good. But to be honest, no
matter how good the reason, I simply can't stand the look of the code. 0=den
just reads completely wrongly to me...

Paul.


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