
Andras Erdei <aerdei <at> gmail.com> writes:
i think the documentation on boost::rational is misleading, and it cannot be used with finite precision (e.g. the built-in) types at all: whenever the result of an operation cannot be represented exactly, it returns something totally bogus
This is true for *any* operations on the built-in types. If you over/under- flow, the results are meaningless.
for example with rational<short> let's try to add 191/181 (=1.055...) and 197/193 (=1.021...) the exact result is 72520/34933 (=2.076...), and we get 6984/-30603 (=-0.229...)!
You didn't state what platform you were running on, but I figure it's likely that shorts are 16 bits. Therefore both the numerator and denominator of the result are out of range (greater than 32768), so there is no possible way that rational<short> can represent this number. What can you expect it to do in such case?
i don't think the intended audience can "code in anticipation of such issues" (the task of determining when these issues come up has the same complexity as doing the actual arithmetic)
I will agree that it's much less obvious when you will get into trouble, since the numbers were of modest magnitude -- though still greater than sqrt(32768) which is a (very rough) indication of potential trouble. (And you did choose a rare case, where all the numerators and denominators are prime numbers.) In this case the obvious solution is rational<long>, but similar examples can of course be created for it. In general, you can never use finite precision and expect accurate results without knowing something about the numbers you are using. That's true for all finite precision types.
fixing rational<> to work with finite precision integers so that for calculations like the above we get the best representable approximation (in this case 3197/1540 = 2.076, precise to 7 digits) is pretty straightforward -- the gcd() function implicitly calculates all representable approximations -- but would require rewriting the whole class
If someone wants the best approximation rather than the exact answer, they would probably just be using floating point. rational is used when people want an exact answer, not just an approximation. I think it would be more useful to add a mechanism (probably optional) for reporting when such overflows ocurred (or some equivalent to floating point NANs and INFs, perhaps). -- Mickey Moore