Files
safe_numerics/doc/boostbook/cpp.xml
Robert Ramey 4153b7f58a Numerous changes to better handle floating point.
Turns out that these changes should also better position us to handle other underlying types - but we're not there yet.
Added example for composition with other types - example boost rational and boost multi precision
Added performance test using boost multi precision
Many other small corrections
2017-07-16 13:36:09 -07:00

193 lines
6.1 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="safe_numerics.promotion_policies.cpp">
<title>cpp&lt;int C, int S, int I, int L, int LL&gt;</title>
<section>
<title>Description</title>
<para>This policy is used to promote safe types in arithmetic expressions
according to the rules in the C++ standard. But rather than using the
native C++ standard types supported by the compiler, it uses types whose
length in number of bits is specified by the template parameters.</para>
<para>This policy is useful for running test programs which use C++
portable integer types but which are destined to run on an architecture
which is different than the one on which the test program is being built
and run. This can happen when developing code for embedded systems.
Algorithms developed or borrowed from one architecture but destined for
another can be tested on the desktop.</para>
<para>Note that this policy is only applicable to safe types whose base
type is a type fulfilling the type requirements of <link
linkend="safe_numerics.integer">Integer</link>. </para>
</section>
<section>
<title>Template Parameters</title>
<informaltable>
<tgroup cols="3">
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="1*"/>
<colspec align="left" colwidth="6*"/>
<thead>
<row>
<entry align="left">Parameter</entry>
<entry align="left">Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>C</code></entry>
<entry>int</entry>
<entry>Number of bits in a char</entry>
</row>
<row>
<entry><code>S</code></entry>
<entry>int</entry>
<entry>Number of bits in a short</entry>
</row>
<row>
<entry><code>I</code></entry>
<entry>int</entry>
<entry>Number of bits in an integer</entry>
</row>
<row>
<entry><code>L</code></entry>
<entry>int</entry>
<entry>Number of bits in a long</entry>
</row>
<row>
<entry><code>LL</code></entry>
<entry>int</entry>
<entry>Number of bits in a long long</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Model of</title>
<para><link
linkend="safe_numerics.promotion_policy">PromotionPolicy</link></para>
</section>
<section>
<title>Example of Use</title>
<para>Consider the following problem. One is developing software which
uses a very small microprocessor and a very limited C compiler. The chip
is so small, you can't print anything from the code, log, debug or
anything else. One debugs this code by using the "burn" and "crash" method
- you burn the chip (download the code), run the code, observe the
results, make changes and try again. This is a crude method which is
usually the one used. But it can be quite time consuming.</para>
<para>Consider an alternative. Build and compile your code in testable
modules. For each module write a test which exercises all the code and
makes it work. Finally download your code into the chip and - voilà -
working product. This sounds great, but there's one problem. Our target
processor - in this case a PIC162550 from Microchip Technology is only an
8 bit CPU. The compiler we use defines INT as 8 bits. This (and a few
other problems), make our algorithm testing environment differ from our
target environment. We can address this by defining INT as a safe integer
with a range of 8 bits. By using a custom promotion policy, we can force
the evaluation of C++ expressions in the test environment to be the same
as that in the target environment. Also in our target environment, we can
trap any overflows or other errors. So we can write and test our code on
our desktop system and download the code to the target knowing that it
just has to work. This is a huge time saver and confidence builder. The
following code is taken from a real project which has used this
method.</para>
<programlisting>#include "../include/safe_integer.hpp"
#include "../include/cpp.hpp"
//////////////////////////////////////////////////////////////
// Stepper Motor Control
// emululate evironment for pic162550
// data widths used by the CCS compiler for pic 16xxx series
using pic16_promotion = boost::numeric::cpp&lt;
8, // char
8, // short - not used by pic 16xxxx
8, // int
16, // long
32 // long long
&gt;;
template &lt;typename T&gt; // T is char, int, etc data type
using safe_t = boost::numeric::safe&lt;
T,
pic16_promotion,
boost::numeric::loose_trap_policy // use for compiling and running tests
&gt;;
using int8 = safe_t&lt;std::int8_t&gt;;
using int16 = safe_t&lt;std::int16_t&gt;;
using int32 = safe_t&lt;std::int32_t&gt;;
using uint8 = safe_t&lt;std::uint8_t&gt;;
using uint16 = safe_t&lt;std::uint16_t&gt;;
using uint32 = safe_t&lt;std::uint32_t&gt;;
////////////////////////////////////////////////////////////////
// Mock defines, functions etc which are in the "real application"
...
// return value in steps
/*
Use the formula:
stopping dist = v **2 / a / 2
*/
uint16 get_stopping_distance(LEMPARAMETER velocity){
int32 d;
d = velocity;
d *= velocity;
d /= lem.acceleration;
d /= 2;
return d;
}
...</programlisting>
<para>Note the usage of the compile time trap policy in order to detect at
compile time any possible error conditions. As I write this, this is still
being refined. Hopefully this will be available by the time you read
this.</para>
</section>
<section>
<title>Header</title>
<para><code><ulink url="../../include/cpp.hpp"><code>#include
&lt;boost/numeric/safe_numerics/cpp.hpp&gt; </code></ulink></code></para>
</section>
</section>