|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r65552 - in sandbox/chrono/libs/ratio/doc: . html
From: vicente.botet_at_[hidden]
Date: 2010-09-23 12:18:45
Author: viboes
Date: 2010-09-23 12:18:44 EDT (Thu, 23 Sep 2010)
New Revision: 65552
URL: http://svn.boost.org/trac/boost/changeset/65552
Log:
Ratio update doc
Binary files modified:
sandbox/chrono/libs/ratio/doc/ratio.pdf
Text files modified:
sandbox/chrono/libs/ratio/doc/html/index.html | 458 +++++++++++++++++++++++++++++++++++++++
sandbox/chrono/libs/ratio/doc/ratio.qbk | 173 +++++++++++++++
2 files changed, 626 insertions(+), 5 deletions(-)
Modified: sandbox/chrono/libs/ratio/doc/html/index.html
==============================================================================
--- sandbox/chrono/libs/ratio/doc/html/index.html (original)
+++ sandbox/chrono/libs/ratio/doc/html/index.html 2010-09-23 12:18:44 EDT (Thu, 23 Sep 2010)
@@ -1500,9 +1500,459 @@
</p>
<p>
Boost.Ratio implementes some simplifications in order to reduce the possibility
- of overflow. The general idea is to use the gcd of some of the possible products
- that can overflow, and simplify before doing the product.
+ of overflow. The general ideas are:
</p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+ The <code class="computeroutput"><span class="identifier">num</span></code> and <code class="computeroutput"><span class="identifier">den</span></code> <code class="computeroutput"><span class="identifier">ratio</span><span class="special"><></span></code> fields are normalized.
+ </li>
+<li>
+ Use the gcd of some of the possible products that can overflow, and simplify
+ before doing the product.
+ </li>
+<li>
+ Use some equivalences relations that avoid addition or substraction can
+ overflow or underflow.
+ </li>
+</ul></div>
+<p>
+ Next follows more detail:
+ </p>
+<p>
+ <span class="bold"><strong>ratio_add</strong></span>
+ </p>
+<p>
+ In
+ </p>
+<pre class="programlisting"><span class="special">(</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)+(</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)=(</span><span class="identifier">n1</span><span class="special">*</span><span class="identifier">d2</span><span class="special">+</span><span class="identifier">n2</span><span class="special">*</span><span class="identifier">d1</span><span class="special">)/(</span><span class="identifier">d1</span><span class="special">*</span><span class="identifier">d2</span><span class="special">)</span>
+</pre>
+<p>
+ either n1*d2+n2*d1 or d1*d2 can overflow.
+ </p>
+<pre class="programlisting"> <span class="special">(</span> <span class="special">(</span><span class="identifier">n1</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">n2</span> <span class="special">*</span> <span class="identifier">d1</span><span class="special">)</span> <span class="special">)</span>
+<span class="special">/</span> <span class="special">(</span><span class="identifier">d1</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)</span>
+</pre>
+<p>
+ Dividing by gcd(d1,d2) on both num and den
+ </p>
+<pre class="programlisting"> <span class="special">(</span> <span class="special">(</span><span class="identifier">n1</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">+</span>
+ <span class="special">(</span><span class="identifier">n2</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span>
+ <span class="special">)</span>
+<span class="special">/</span> <span class="special">((</span><span class="identifier">d1</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))</span>
+</pre>
+<p>
+ Multipliying and diving by gcd(n1,n2) in numerator
+ </p>
+<pre class="programlisting"> <span class="special">(</span> <span class="special">((</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)*(</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)))</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">+</span>
+ <span class="special">((</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)*(</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)))</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span>
+ <span class="special">)</span>
+<span class="special">/</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">d1</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)</span> <span class="special">)</span>
+</pre>
+<p>
+ Factorizing gcd(n1,n2)
+ </p>
+<pre class="programlisting"> <span class="special">(</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)</span> <span class="special">*</span>
+ <span class="special">(</span> <span class="special">((</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">+</span> <span class="special">((</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(<
/span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">)</span>
+ <span class="special">)</span>
+<span class="special">/</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">d1</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)</span> <span class="special">)</span>
+</pre>
+<p>
+ Regrouping
+ </p>
+<pre class="programlisting"> <span class="special">(</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)</span> <span class="special">*</span>
+ <span class="special">(</span> <span class="special">((</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">+</span> <span class="special">((</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(<
/span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">)</span>
+ <span class="special">)</span>
+<span class="special">/</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">d1</span> <span class="special">/</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))</span> <span class="special">*</span> <span class="identifier">d2</span> <span class="special">)</span>
+</pre>
+<p>
+ Dividing by (d1 / gcd(d1,d2))
+ </p>
+<pre class="programlisting"> <span class="special">(</span> <span class="special">(</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">d1</span> <span class="special">/</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))</span> <span class="special">)</span> <span class="special">*</span>
+ <span class="special">(</span> <span class="special">((</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">+</span> <span class="special">((</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(<
/span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">)</span>
+ <span class="special">)</span>
+<span class="special">/</span> <span class="identifier">d2</span>
+</pre>
+<p>
+ Dividing by d2
+ </p>
+<pre class="programlisting"><span class="special">(</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">)</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">d1</span> <span class="special">/</span> <span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))</span> <span class="special">)</span> <span class="special">*</span>
+<span class="special">(</span> <span class="special">((</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">+</span> <span class="special">((</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">n2</span><span class="special">))</span> <span class="special">*</span> <span class="special">(</spa
n><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcd</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span> <span class="special">/</span> <span class="identifier">d2</span> <span class="special">)</span>
+</pre>
+<p>
+ This expression correspond to the multiply of two ratios that have less risk
+ of overflow as the initial numerators and denomitators appear now in most
+ of the cases divided by a gcd.
+ </p>
+<p>
+ For ratio_subtract the reasoning is the same
+ </p>
+<p>
+ <span class="bold"><strong>ratio_multiply</strong></span>
+ </p>
+<p>
+ In
+ </p>
+<pre class="programlisting"><span class="special">(</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)*(</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)=((</span><span class="identifier">n1</span><span class="special">*</span><span class="identifier">n2</span><span class="special">)/(</span><span class="identifier">d1</span><span class="special">*</span><span class="identifier">d2</span><span class="special">))</span>
+</pre>
+<p>
+ either n1*n2 or d1*d2 can overflow.
+ </p>
+<p>
+ Dividing by gcc(n1,d2) numerator and denominator
+ </p>
+<pre class="programlisting"> <span class="special">(((</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcc</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))*</span><span class="identifier">n2</span><span class="special">)</span>
+<span class="special">/</span> <span class="special">(</span><span class="identifier">d1</span><span class="special">*(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcc</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))))</span>
+</pre>
+<p>
+ Dividing by gcc(n2,d1)
+ </p>
+<pre class="programlisting"> <span class="special">((</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">gcc</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">))*(</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">gcc</span><span class="special">(</span><span class="identifier">n2</span><span class="special">,</span><span class="identifier">d1</span><span class="special">)))</span>
+<span class="special">/</span> <span class="special">((</span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">gcc</span><span class="special">(</span><span class="identifier">n2</span><span class="special">,</span><span class="identifier">d1</span><span class="special">))*(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">gcc</span><span class="special">(</span><span class="identifier">n1</span><span class="special">,</span><span class="identifier">d2</span><span class="special">)))</span>
+</pre>
+<p>
+ And now all the initial numerator and denominators have been reduced, avoiding
+ the overflow.
+ </p>
+<p>
+ For ratio_divide the reasoning is similar.
+ </p>
+<p>
+ <span class="bold"><strong>ratio_less</strong></span>
+ </p>
+<p>
+ In order to evaluate
+ </p>
+<pre class="programlisting"><span class="special">(</span><span class="identifier">n1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)<(</span><span class="identifier">n2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+</pre>
+<p>
+ without moving to floating point numbers, two techniques are used:
+ </p>
+<div class="itemizedlist"><ul type="disc"><li>
+ First compare the sign of the numerators
+ </li></ul></div>
+<p>
+ If sign(n1) < sign(n2) the result is true.
+ </p>
+<p>
+ If sign(n1) == sign(n2) the result depends on the following after making
+ the numerators positive
+ </p>
+<div class="itemizedlist"><ul type="disc"><li>
+ When the sign is equal the technique used is to work with integer division
+ and modulo when the signs are equal.
+ </li></ul></div>
+<p>
+ Let call Qi the integer division of ni and di and Mi the modulo of ni and
+ di.
+ </p>
+<pre class="programlisting"><span class="identifier">ni</span> <span class="special">=</span> <span class="identifier">Qi</span> <span class="special">*</span> <span class="identifier">di</span> <span class="special">+</span> <span class="identifier">Mi</span> <span class="keyword">and</span> <span class="identifier">Mi</span> <span class="special"><</span> <span class="identifier">di</span>
+</pre>
+<p>
+ Form
+ </p>
+<pre class="programlisting"><span class="special">((</span><span class="identifier">n1</span><span class="special">*</span><span class="identifier">d2</span><span class="special">)<(</span><span class="identifier">d1</span><span class="special">*</span><span class="identifier">n2</span><span class="special">))</span>
+</pre>
+<p>
+ we get
+ </p>
+<pre class="programlisting"><span class="special">(((</span><span class="identifier">Q1</span> <span class="special">*</span> <span class="identifier">d1</span> <span class="special">+</span> <span class="identifier">M1</span><span class="special">)*</span><span class="identifier">d2</span><span class="special">)<(</span><span class="identifier">d1</span><span class="special">*((</span><span class="identifier">Q2</span> <span class="special">*</span> <span class="identifier">d2</span> <span class="special">+</span> <span class="identifier">M2</span><span class="special">))))</span>
+</pre>
+<p>
+ Developing
+ </p>
+<pre class="programlisting"><span class="special">((</span><span class="identifier">Q1</span> <span class="special">*</span> <span class="identifier">d1</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)+</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">*</span><span class="identifier">d2</span><span class="special">))<((</span><span class="identifier">d1</span> <span class="special">*</span> <span class="identifier">Q2</span> <span class="special">*</span> <span class="identifier">d2</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">d1</span><span class="special">*</span><span class="identifier">M2</span><span class="special">))</span>
+</pre>
+<p>
+ Dividing by d1*d2
+ </p>
+<pre class="programlisting"><span class="identifier">Q1</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="identifier">Q2</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+</pre>
+<p>
+ If Q1=Q2 the result depends on
+ </p>
+<pre class="programlisting"><span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+</pre>
+<p>
+ If M1<code class="literal">=0</code>=M2 the result is false
+ </p>
+<p>
+ If M1=0 M2!=0 the result is true
+ </p>
+<p>
+ If M1!<code class="literal">0 M2</code>=0 the result is false
+ </p>
+<p>
+ If M1!=0 M2!=0 the result depends on
+ </p>
+<pre class="programlisting"><span class="special">(</span><span class="identifier">d2</span><span class="special">/</span><span class="identifier">M2</span><span class="special">)</span> <span class="special"><</span> <span class="special">(</span><span class="identifier">d1</span><span class="special">/</span><span class="identifier">M1</span><span class="special">)</span>
+</pre>
+<p>
+ If Q1!=Q2, the result of
+ </p>
+<pre class="programlisting"><span class="identifier">Q1</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="identifier">Q2</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+</pre>
+<p>
+ depends only on Q1 and Q2 as Qi are integers and (Mi/di) <1 because Mi<di.
+ </p>
+<p>
+ if Q1>Q2, Q1==Q2+k, k>=1
+ </p>
+<pre class="programlisting"><span class="identifier">Q2</span><span class="special">+</span><span class="identifier">k</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="identifier">Q2</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+<span class="identifier">k</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+<span class="identifier">k</span> <span class="special"><</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span> <span class="special">-</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span>
+</pre>
+<p>
+ but the difference between two numbers between 0 and 1 can not be greater
+ than 1, so the result is false.
+ </p>
+<p>
+ if Q2>Q1, Q2==Q1+k, k>=1
+ </p>
+<pre class="programlisting"><span class="identifier">Q1</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="identifier">Q1</span><span class="special">+</span><span class="identifier">k</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+<span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special"><</span> <span class="identifier">k</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span>
+<span class="special">(</span><span class="identifier">M1</span><span class="special">/</span><span class="identifier">d1</span><span class="special">)</span> <span class="special">-</span> <span class="special">(</span><span class="identifier">M2</span><span class="special">/</span><span class="identifier">d2</span><span class="special">)</span> <span class="special"><</span> <span class="identifier">k</span>
+</pre>
+<p>
+ which is always true, so the result is true.
+ </p>
+<p>
+ The following table recapitulates this analisys
+ </p>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+<col>
+<col>
+<col>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+ <p>
+ ratio<n1,d1>
+ </p>
+ </th>
+<th>
+ <p>
+ ratio<n2,d2>
+ </p>
+ </th>
+<th>
+ <p>
+ Q1
+ </p>
+ </th>
+<th>
+ <p>
+ Q2
+ </p>
+ </th>
+<th>
+ <p>
+ M1
+ </p>
+ </th>
+<th>
+ <p>
+ M2
+ </p>
+ </th>
+<th>
+ <p>
+ Result
+ </p>
+ </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+ <p>
+ ratio<n1,d1>
+ </p>
+ </td>
+<td>
+ <p>
+ ratio<n2,d2>
+ </p>
+ </td>
+<td>
+ <p>
+ Q1
+ </p>
+ </td>
+<td>
+ <p>
+ Q2
+ </p>
+ </td>
+<td>
+ <p>
+ !=0
+ </p>
+ </td>
+<td>
+ <p>
+ !=0
+ </p>
+ </td>
+<td>
+ <p>
+ Odd ? Q2 < Q1 : Q1 < Q2
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ ratio<n1,d1>
+ </p>
+ </td>
+<td>
+ <p>
+ ratio<n2,d2>
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ 0
+ </p>
+ </td>
+<td>
+ <p>
+ 0
+ </p>
+ </td>
+<td>
+ <p>
+ false
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ ratio<n1,d1>
+ </p>
+ </td>
+<td>
+ <p>
+ ratio<n2,d2>
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ 0
+ </p>
+ </td>
+<td>
+ <p>
+ !=0
+ </p>
+ </td>
+<td>
+ <p>
+ true
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ ratio<n1,d1>
+ </p>
+ </td>
+<td>
+ <p>
+ ratio<n2,d2>
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ !=0
+ </p>
+ </td>
+<td>
+ <p>
+ 0
+ </p>
+ </td>
+<td>
+ <p>
+ false
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
+ ratio<n1,d1>
+ </p>
+ </td>
+<td>
+ <p>
+ ratio<n2,d2>
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ Q
+ </p>
+ </td>
+<td>
+ <p>
+ !=0
+ </p>
+ </td>
+<td>
+ <p>
+ !=0
+ </p>
+ </td>
+<td>
+ <p>
+ ratio_less<ratio<d2,M2>, ratio<d1/M1>>
+ </p>
+ </td>
+</tr>
+</tbody>
+</table></div>
</div>
<div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title">
<a name="boost_ratio.appendices.faq"></a> Appendix D: FAQ
@@ -2331,7 +2781,7 @@
<a name="boost_ratio.appendices.todo"></a> Appendix H: Future plans
</h3></div></div></div>
<a name="boost_ratio.appendices.todo.for_later_releases"></a><h4>
-<a name="id5013689"></a>
+<a name="id5017727"></a>
<a href="index.html#boost_ratio.appendices.todo.for_later_releases">For later
releases</a>
</h4>
@@ -2343,7 +2793,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
-<td align="left"><p><small>Last revised: September 23, 2010 at 05:36:54 GMT</small></p></td>
+<td align="left"><p><small>Last revised: September 23, 2010 at 10:28:54 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
Modified: sandbox/chrono/libs/ratio/doc/ratio.pdf
==============================================================================
Binary files. No diff available.
Modified: sandbox/chrono/libs/ratio/doc/ratio.qbk
==============================================================================
--- sandbox/chrono/libs/ratio/doc/ratio.qbk (original)
+++ sandbox/chrono/libs/ratio/doc/ratio.qbk 2010-09-23 12:18:44 EDT (Thu, 23 Sep 2010)
@@ -1054,7 +1054,178 @@
When the result is representable, but a simple application of arithmetic rules would result in overflow, e.g. `ratio_multiply<ratio<INTMAX_MAX,2>,ratio<2,INTMAX_MAX>>` can be reduced to `ratio<1,1>`, but the direct result of `ratio<INTMAX_MAX*2,INTMAX_MAX*2>` would result in overflow.
-Boost.Ratio implementes some simplifications in order to reduce the possibility of overflow. The general idea is to use the gcd of some of the possible products that can overflow, and simplify before doing the product.
+Boost.Ratio implementes some simplifications in order to reduce the possibility of overflow. The general ideas are:
+
+* The `num` and `den` `ratio<>` fields are normalized.
+* Use the gcd of some of the possible products that can overflow, and simplify before doing the product.
+* Use some equivalences relations that avoid addition or substraction can overflow or underflow.
+
+
+Next follows more detail:
+
+[*ratio_add]
+
+In
+
+ (n1/d1)+(n2/d2)=(n1*d2+n2*d1)/(d1*d2)
+
+either n1*d2+n2*d1 or d1*d2 can overflow.
+
+ ( (n1 * d2) + (n2 * d1) )
+ / (d1 * d2)
+
+Dividing by gcd(d1,d2) on both num and den
+
+ ( (n1 * (d2/gcd(d1,d2))) +
+ (n2 * (d1/gcd(d1,d2)))
+ )
+ / ((d1 * d2) / gcd(d1,d2))
+
+
+Multipliying and diving by gcd(n1,n2) in numerator
+
+ ( ((gcd(n1,n2)*(n1/gcd(n1,n2))) * (d2/gcd(d1,d2))) +
+ ((gcd(n1,n2)*(n2/gcd(n1,n2))) * (d1/gcd(d1,d2)))
+ )
+ / ( (d1 * d2) / gcd(d1,d2) )
+
+Factorizing gcd(n1,n2)
+
+ ( gcd(n1,n2) *
+ ( ((n1/gcd(n1,n2)) * (d2/gcd(d1,d2))) + ((n2/gcd(n1,n2)) * (d1/gcd(d1,d2))) )
+ )
+ / ( (d1 * d2) / gcd(d1,d2) )
+
+Regrouping
+
+ ( gcd(n1,n2) *
+ ( ((n1/gcd(n1,n2)) * (d2/gcd(d1,d2))) + ((n2/gcd(n1,n2)) * (d1/gcd(d1,d2))) )
+ )
+ / ( (d1 / gcd(d1,d2)) * d2 )
+
+Dividing by (d1 / gcd(d1,d2))
+
+ ( ( gcd(n1,n2) / (d1 / gcd(d1,d2)) ) *
+ ( ((n1/gcd(n1,n2)) * (d2/gcd(d1,d2))) + ((n2/gcd(n1,n2)) * (d1/gcd(d1,d2))) )
+ )
+ / d2
+
+
+Dividing by d2
+
+ ( gcd(n1,n2) / (d1 / gcd(d1,d2)) ) *
+ ( ((n1/gcd(n1,n2)) * (d2/gcd(d1,d2))) + ((n2/gcd(n1,n2)) * (d1/gcd(d1,d2))) / d2 )
+
+This expression correspond to the multiply of two ratios that have less risk of overflow as the initial numerators and denomitators appear now in most of the cases divided by a gcd.
+
+
+For ratio_subtract the reasoning is the same
+
+[*ratio_multiply]
+
+In
+
+ (n1/d1)*(n2/d2)=((n1*n2)/(d1*d2))
+
+either n1*n2 or d1*d2 can overflow.
+
+Dividing by gcc(n1,d2) numerator and denominator
+
+ (((n1/gcc(n1,d2))*n2)
+ / (d1*(d2/gcc(n1,d2))))
+
+Dividing by gcc(n2,d1)
+
+ ((n1/gcc(n1,d2))*(n2/gcc(n2,d1)))
+ / ((d1/gcc(n2,d1))*(d2/gcc(n1,d2)))
+
+And now all the initial numerator and denominators have been reduced, avoiding the overflow.
+
+For ratio_divide the reasoning is similar.
+
+[*ratio_less]
+
+In order to evaluate
+
+ (n1/d1)<(n2/d2)
+
+without moving to floating point numbers, two techniques are used:
+
+* First compare the sign of the numerators
+
+If sign(n1) < sign(n2) the result is true.
+
+If sign(n1) == sign(n2) the result depends on the following after making the numerators positive
+
+* When the sign is equal the technique used is to work with integer division and modulo when the signs are equal.
+
+Let call Qi the integer division of ni and di and Mi the modulo of ni and di.
+
+ ni = Qi * di + Mi and Mi < di
+
+Form
+
+ ((n1*d2)<(d1*n2))
+
+we get
+
+ (((Q1 * d1 + M1)*d2)<(d1*((Q2 * d2 + M2))))
+
+Developing
+
+ ((Q1 * d1 * d2)+ (M1*d2))<((d1 * Q2 * d2) + (d1*M2))
+
+Dividing by d1*d2
+
+ Q1 + (M1/d1) < Q2 + (M2/d2)
+
+If Q1=Q2 the result depends on
+
+ (M1/d1) < (M2/d2)
+
+If M1==0==M2 the result is false
+
+If M1=0 M2!=0 the result is true
+
+If M1!=0 M2==0 the result is false
+
+If M1!=0 M2!=0 the result depends on
+
+ (d2/M2) < (d1/M1)
+
+If Q1!=Q2, the result of
+
+ Q1 + (M1/d1) < Q2 + (M2/d2)
+
+depends only on Q1 and Q2 as Qi are integers and (Mi/di) <1 because Mi<di.
+
+if Q1>Q2, Q1==Q2+k, k>=1
+
+ Q2+k + (M1/d1) < Q2 + (M2/d2)
+ k + (M1/d1) < (M2/d2)
+ k < (M2/d2) - (M1/d1)
+
+but the difference between two numbers between 0 and 1 can not be greater than 1, so the result is false.
+
+if Q2>Q1, Q2==Q1+k, k>=1
+
+ Q1 + (M1/d1) < Q1+k + (M2/d2)
+ (M1/d1) < k + (M2/d2)
+ (M1/d1) - (M2/d2) < k
+
+which is always true, so the result is true.
+
+The following table recapitulates this analisys
+
+[table
+ [[ratio<n1,d1>][ratio<n2,d2>] [Q1] [Q2] [M1] [M2] [Result]]
+ [[ratio<n1,d1>][ratio<n2,d2>] [Q1] [Q2] [!=0] [!=0] [Odd ? Q2 < Q1 : Q1 < Q2]]
+ [[ratio<n1,d1>][ratio<n2,d2>] [Q] [Q] [0] [0] [false]]
+ [[ratio<n1,d1>][ratio<n2,d2>] [Q] [Q] [0] [!=0] [true]]
+ [[ratio<n1,d1>][ratio<n2,d2>] [Q] [Q] [!=0] [0] [false]]
+ [[ratio<n1,d1>][ratio<n2,d2>] [Q] [Q] [!=0] [!=0] [ratio_less<ratio<d2,M2>, ratio<d1/M1>>]]
+]
+
[endsect]
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk