safe_numerics/doc/boostbook/rational.xml
Robert Ramey b62ef86e28 Added case study for embedded system
corrections in cpp promotion
added make_safe_literal
separated integers from other types
dropped example91
updated CMakeLists.txt and Jamfile.v2 accordingly
2018-07-21 09:57:35 -07:00

71 lines
3.6 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<section id="safe_numerics.composition_with_other_libraries">
<title>Composition with Other Libraries</title>
<?dbhtml stop-chunking?>
<para>For many years, Boost has included a library to represent and operate
on <ulink url="http://www.boost.org/doc/libs/1_64_0/libs/rational/">rational
numbers</ulink>. Its well crafted, has good documentation and is well
maintained. Using the rational library is as easy as construction an
instance with the expression <code>rational r(n, d)</code> where n and d are
integers of the same type. From then on it can be used pretty much as any
other number. Reading the documentation with safe integers in mind one
finds<blockquote>
<para>Limited-precision integer types [such as <code>int</code>] may
raise issues with the range sizes of their allowable negative values and
positive values. If the negative range is larger, then the
extremely-negative numbers will not have an additive inverse in the
positive range, making them unusable as denominator values since they
cannot be normalized to positive values (unless the user is lucky enough
that the input components are not relatively prime
pre-normalization).</para>
</blockquote>Which hints of trouble. Examination of the code reveals which
suggest that care has been taken implement operations so as to avoid
overflows, catch divide by zero, etc. But the code itself doesn't seem to
consistently implement this idea. So we make a small demo program:
<programlisting><xi:include href="../../example/example15.cpp" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>which
produces the following output<screen>r = 1/2
q = -1/2
r * q = -1/4
c = 1/2147483647
d = 1/2
c * d = 1/-2
c = 1/2147483647
d = 1/2
c * d = multiplication overflow: positive overflow error
</screen></para>
<para>The <ulink
url="http://www.boost.org/doc/libs/1_64_0/libs/rational/">rational library
documentation</ulink> is quite specific as to the <ulink
url="http://www.boost.org/doc/libs/1_64_0/libs/rational/rational.html#Integer%20Type%20Requirements">type
requirements</ulink> placed on the underlying type. Turns out the our <link
linkend="safe_numerics.integer">own definition of an integer type</link>
fulfills (actually surpasses) these requirements. So we have reason to hope
that we can use <code>safe&lt;int&gt;</code> as the underlying type to
create what we might call a "<code>safe_rational</code>". This we have done
in the above example where we demonstrate how to compose the rational
library with the safe numerics library in order to create what amounts to a
safe_rational library - all without writing a line of code! Still, things
are not perfect. Since the <ulink
url="http://www.boost.org/doc/libs/1_64_0/libs/rational/">rational numbers
library</ulink> implements its own checking for divide by zero by throwing
an exception, the safe numerics code for handling this - included exception
policy will not be respected. To summarize:<itemizedlist>
<listitem>
<para>In some cases safe types can be used as template parameters to
other types to inject the concept of "no erroneous results" into the
target type.</para>
</listitem>
<listitem>
<para>Such composition is not guaranteed to work. The target type must
be reviewed in some detail.</para>
</listitem>
</itemizedlist></para>
</section>