mirror of
https://github.com/boostorg/safe_numerics.git
synced 2026-02-15 13:22:18 +00:00
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
193 lines
6.1 KiB
XML
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<int C, int S, int I, int L, int LL></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<
|
|
8, // char
|
|
8, // short - not used by pic 16xxxx
|
|
8, // int
|
|
16, // long
|
|
32 // long long
|
|
>;
|
|
|
|
template <typename T> // T is char, int, etc data type
|
|
using safe_t = boost::numeric::safe<
|
|
T,
|
|
pic16_promotion,
|
|
boost::numeric::loose_trap_policy // use for compiling and running tests
|
|
>;
|
|
|
|
using int8 = safe_t<std::int8_t>;
|
|
using int16 = safe_t<std::int16_t>;
|
|
using int32 = safe_t<std::int32_t>;
|
|
using uint8 = safe_t<std::uint8_t>;
|
|
using uint16 = safe_t<std::uint16_t>;
|
|
using uint32 = safe_t<std::uint32_t>;
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// 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
|
|
<boost/numeric/safe_numerics/cpp.hpp> </code></ulink></code></para>
|
|
</section>
|
|
</section>
|