rational.xml 3.6 KB

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