title: How to use Boost::Geometry _union with integers
body: <p>I'm trying to use Boost::Geometry _union with integers, for both performance and numeric accuracy. For that, I multiply the coordinates of my input with 10,000. Thus creating coordinates with up to 9 digits. I figured that since I use 64-bit integers, that should work well.</p>
  
  <p>Unfortunately, when I run the code, I get strange results (the output polygon includes a point that is far from any polygon in the input). Investigating the code of Boost::Geometry brought me to the conclusion that the origin is a wrap-around problem in the file cart_intersect.hpp:</p>
  
  <pre><code>set&lt;1&gt;(point, get&lt;0, 1&gt;(segment) + boost::numeric_cast
              &lt;
                  CoordinateType
              &gt;(numerator * dy_promoted / denominator));
  </code></pre>
  
  <p>When all three (numerator,dy_promoted and denominator) are huge, the result of the multiplication takes more than 64-bit, and therefore the whole result is incorrect.</p>
  
  <p>Is the use of Boost::Geometry with such big integers valid? What is the correct way to use Boost::Geometry with integers while maintaining correctness and precision?</p>
  
  <hr>
  
  <p><strong>Edit</strong>
  @sehe, thanks for your response. Here is an SSCCE, compiled with VS2013 and Boost 1.63</p>
  
  <pre><code>#include &lt;boost/geometry/geometry.hpp&gt;
  #include &lt;boost/geometry/geometries/polygon.hpp&gt;
  #include &lt;boost/geometry/geometries/point_xy.hpp&gt;
  #include &lt;boost/geometry/multi/geometries/multi_polygon.hpp&gt; 
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  using namespace std;
  namespace bg = boost::geometry;
  
  typedef bg::model::d2::point_xy&lt;long long, bg::cs::cartesian&gt; TPoint;
  typedef bg::model::ring&lt;TPoint&gt; TRing;
  typedef bg::model::polygon&lt;TPoint&gt; TPolygon;
  typedef bg::model::multi_polygon&lt;TPolygon&gt; TMultiPolygon;
  
  void PrintRing(const TRing&amp; rng)
  {
    for (const auto&amp; ver : rng)
    {
      cout &lt;&lt; "(" &lt;&lt; ver.x() &lt;&lt; "," &lt;&lt; ver.y() &lt;&lt; "),";
    }
  }
  
  void PrintPolygon(const TPolygon&amp; pol)
  {
    cout &lt;&lt; "Outer: ";
    PrintRing(pol.outer());
    cout &lt;&lt; endl;
  
    for (const auto&amp; rng : pol.inners())
    {
      cout &lt;&lt; "Inner: ";
      PrintRing(rng);
      cout &lt;&lt; endl;
    }
  }
  
  void PrintMultiPolygon(const string name, const TMultiPolygon&amp; mp)
  {
    cout &lt;&lt; "Multi-Polygon " &lt;&lt; name &lt;&lt; " : " &lt;&lt; endl;
    for (const auto&amp; pol : mp)
    {
      PrintPolygon(pol);
    }
    cout &lt;&lt; endl;
  }
  
  int main()
  {
    cout &lt;&lt; "BOOST_LIB_VERSION: " &lt;&lt; BOOST_LIB_VERSION &lt;&lt; endl;
    const vector&lt;TPoint&gt; verticesA{ { -405129, 2010409 }, { 3370580, 2010409 }, { 3370580, 1997709 }, { -405129, 1997709 }, { -405129, 2010409 } };
    const TRing rngA(verticesA.cbegin(), verticesA.cend());
    TPolygon polA;
    polA.outer() = rngA;
    TMultiPolygon mpA;
    mpA.push_back(polA);
  
    const vector&lt;TPoint&gt; verticesB{ { 3364230, -895349 }, { 3364230, 2004060 }, { 3376930, 2004059 }, { 3376930, -895350 }, { 3364230, -895349 } };
    const TRing rngB(verticesB.cbegin(), verticesB.cend());
    TPolygon polB;
    polB.outer() = rngB;
    TMultiPolygon mpB;
    mpB.push_back(polB);
  
    TMultiPolygon output;
  
    bg::union_(mpA, mpB, output);
  
    PrintMultiPolygon("A", mpA);
    PrintMultiPolygon("B", mpB);
    PrintMultiPolygon("output", output);
  }
  </code></pre>
  
  <hr>
  
  <p>The output of the program is:</p>
  
  <blockquote>
    <p><code>BOOST_LIB_VERSION: 1_63</code><br/>
    <br/>
    <code>Multi-Polygon A :</code><br/>
    <code>Outer: (-405129,2010409),(3370580,2010409),(3370580,1997709),(-405129,1997709),(-405129,2010409),</code><br/>
    <br/>
    <code>Multi-Polygon B :</code><br/>
    <code>Outer: (3364230,-895349),(3364230,2004060),(3376930,2004059),(3376930,-895350),(3364230,-895349),</code><br/>
    <br/>
    <code>Multi-Polygon output :</code><br/>
    <code>Outer: (3370580,2004060),(3376930,2004059),(3376930,-895350),(3364230,-895349),</code><strong><code>(3364230,-1372382)</code></strong><code>,(-405129,1997709),(-405129,2010409),(3370580,2010409),(3370580,2004060),</code><br/></p>
  </blockquote>
  
  <p>Note the coordinates in bold, the Y value is farther than any Y coordinate in the input.</p>