Boost C++ Libraries: Ticket #12268: Boost Polygon: Overflow issue with euclidean_distance() when using large (32-bit) coordinates. https://svn.boost.org/trac10/ticket/12268 <p> Hi, </p> <p> When using large (32-bit) ints for coordinates, there seems to be a problem in getting the correct result with boost::polygon::euclidean_distance(). The sample program demonstrates the issue (compiled with GCC 4.7.3 + Boost 1.61.0). </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;cmath&gt; #include &lt;boost/polygon/polygon.hpp&gt; #include &lt;boost/geometry.hpp&gt; namespace gtl = boost::polygon; using namespace boost::polygon::operators; typedef gtl::rectangle_data&lt;int&gt; LayoutRectangle; int main(int argc, char** argv) { LayoutRectangle t(16740130,29759232,16740350,29760652); LayoutRectangle n(16808130,29980632,16808350,29982052); std::cout &lt;&lt; gtl::euclidean_distance(t, n) &lt;&lt; std::endl; std::cout &lt;&lt; gtl::euclidean_distance(t, n, gtl::HORIZONTAL) &lt;&lt; " " &lt;&lt; gtl::euclidean_distance(t, n, gtl::VERTICAL) &lt;&lt; std::endl; std::cout &lt;&lt; gtl::square_euclidean_distance(t, n) &lt;&lt; std::endl; std::cout &lt;&lt; std::sqrt(gtl::square_euclidean_distance(t, n)) &lt;&lt; std::endl; std::cout &lt;&lt; (int) std::sqrt(gtl::square_euclidean_distance(t, n)) &lt;&lt; std::endl; return 0; } </pre><p> The output of this program is: </p> <p> 38022.6 67780 219980 52985328800 230185 230185 </p> <p> 230185 is the correct answer, but euclidean_distance() gives 38022.6. I traced the program above in GDB, and the culprit seems to be 'return (xdist * xdist) + (ydist * ydist)' in the library code shown below. xdist/ydist have correct values but taking the square root is most likely causing overflow. </p> <p> rectangle_concept.hpp: </p> <pre class="wiki"> square_euclidean_distance(const rectangle_type&amp; lvalue, const rectangle_type_2&amp; rvalue) { typename coordinate_traits&lt;typename rectangle_coordinate_type&lt;rectangle_type&gt;::type&gt;::coordinate_difference xdist, ydist; xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); ydist = euclidean_distance(lvalue, rvalue, VERTICAL); return (xdist * xdist) + (ydist * ydist); } </pre><p> I notice coordinate_difference is defined as 'long long' which is 8 bytes (sizeof(long long)) on my machine. So not sure why this is happening. </p> <p> I also posted this as a question on stackoverflow: <a class="ext-link" href="http://stackoverflow.com/questions/37804930/boost-polygon-issue-with-euclidean-distance"><span class="icon">​</span>http://stackoverflow.com/questions/37804930/boost-polygon-issue-with-euclidean-distance</a> </p> <p> For now, I can use std::sqrt(gtl::square_euclidean_distance())' as a workaround. Thanks. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12268 Trac 1.4.3 Pallav Gupta <drpallavgupta@…> Tue, 14 Jun 2016 07:52:19 GMT summary changed https://svn.boost.org/trac10/ticket/12268#comment:1 https://svn.boost.org/trac10/ticket/12268#comment:1 <ul> <li><strong>summary</strong> <span class="trac-field-old">Boost Polygon: Overflow issue with euclidean_distance() when using large (32-int) coordinates.</span> → <span class="trac-field-new">Boost Polygon: Overflow issue with euclidean_distance() when using large (32-bit) coordinates.</span> </li> </ul> Ticket anonymous Wed, 15 Jun 2016 20:49:28 GMT <link>https://svn.boost.org/trac10/ticket/12268#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12268#comment:2</guid> <description> <p> I think the problem is in the code fragment below. Don't know why the return value of square_euclidean_distance() is being casted on an 'int'. </p> <pre class="wiki"> template &lt;typename rectangle_type, typename rectangle_type_2&gt; typename enable_if&lt; typename gtl_and_3&lt;y_r_edist2, typename is_rectangle_concept&lt;typename geometry_concept&lt;rectangle_type&gt;::type&gt;::type, typename is_rectangle_concept&lt;typename geometry_concept&lt;rectangle_type_2&gt;::type&gt;::type&gt;::type, typename rectangle_distance_type&lt;rectangle_type&gt;::type&gt;::type euclidean_distance(const rectangle_type&amp; lvalue, const rectangle_type_2&amp; rvalue) { double val = (int)square_euclidean_distance(lvalue, rvalue); return std::sqrt(val); } </pre> </description> <category>Ticket</category> </item> </channel> </rss>