 # Boost :

From: Andras Erdei (aerdei_at_[hidden])
Date: 2005-04-06 03:04:56

On Mar 28, 2005 1:29 PM, Andy Little <andy_at_[hidden]> wrote:

> Surely int should be the default parameter (if any). Using bigint turns
> it from a relatively lightweight to a heavyweight type.

agreed

> In many uses of rational the values are unlikely to overflow. Some uses are
> in dividing a circle into degrees, minutes, or seconds, power of dimension in
> a runtime physical-quantity, Storing imperial lengths eg 1 1/8 " (inch).

the range of the values has nothing to do with the kind of "overflow" we are
talking about; the same way as int or float "overflows" even for small values
like 1 divided by 3, rational<> will overflow -- if you recall, there was an
example at the very beginning of this discussion where adding 1.xxx to 2.xxx
resulted in a negative number with boost::rational<>

my guess is that the only application where it does not happen is where you in
fact only multiply rational<>s with integers (there was a poster who did
this), but you do not need rational<> for that -- maybe your dividing a circle
is such an application, but using imperial lengths (even adding two small
ones) is not

> I would guess that these are the major uses of rational and all have values
> in quite a small range.

it is very hard to make guesses about the major uses of rational (all we know
for sure is our own interest in this)

we all want more precise and reliable results, as cheap as possible, and when
selecting the arithmetic we use, we make a compromise

in some cases (e.g. cryptography) no compromise is acceptable, and there is no
choice but to avoid finite precision calculations entirely

in most cases we stick with floats, because due to the hardware support they
are fast, and most people simply does not know how bad floating point
arithmetic really is

there are some problems with finite precision (e.g. algebraically equivalent
definitions yielding different results due to rounding) that cannot be
avoided, but floating point adds its own artifacts on top of this; it was
inroduced because it was something that could be implemented efficiently
given the knowledge and hardware of those days, and that single advantage

i can enumerate problems with floating-point endlessly; e.g. in CAD
applications these are usually not that we get a result that is not precise
enough, but that we get results that are topologically inconsistent, leading
to polygons that are convex and concave at same time, points being both before
and after another on a line and so on, the end result being correct algorithms
getting into infinite loops, aborting or giving impossible results

these problems are often solved by obscuring algorithms using tricks,
maintaining the history of how these points were calculated (what lines do
they match, and what is their ordering), introducing epsiloning (which is an
empirical process you can never fully trust) and many other ad-hoc methods
(and also by using alternative aritmetic, like interval and lazy)

my guess on the major usage of rational<> would be people burnt by floats
making CAD, image processing, signal processing, statistical etc applications

> And of course making bigint the default parameter introduces a
> dependency, which is at least untidy.

agreed

> BTW why doesnt boost::rational have a 'value_type' member rather than the
> obscure 'int_type'?

imho rational<> should not have any of these

it is not necessary to limit rational<> to use the same type for representing
the numerator and denominator, so there is no single value_type/int_type to
publish

it is not necessary to limit rational<> to represent the numerator and
denominator in separate members (i've posted a much more efficient
implementation of the current boost::rational<> which requires both the
numerator and denominator to be stored in the same data member to be
efficient), so the published value_type/int_type may not convey any useful
information for the users of rational<>, as you cannot define how is it
related to rational<>

> As far as errors due to overflow, the problem is not actually in the
> domain of rational but of the value_type as has been stated before.

stated, but not convincingly explained :O)

> rational shouldnt need to know anything about the behaviour of its
> value_types operations.

but that requirement results in rational<>s that are both inefficient and
useless (cannot round)

br,
andras