Fixed 64bit coordinate mode: numerical stability for DRC and LVS enabling. Main problem is representation of the 'world' box which does not transform properly when going through double.

This commit is contained in:
Matthias Koefferlein 2024-01-03 01:57:27 +01:00
parent 6c8d97adc9
commit 38de2d685f
5 changed files with 82 additions and 1 deletions

View File

@ -40,6 +40,21 @@ namespace db {
template <class Coord> class generic_repository;
class ArrayRepository;
template <class C>
inline C box_world_min () { return std::numeric_limits<C>::min (); }
template <class C>
inline C box_world_max () { return std::numeric_limits<C>::max (); }
// NOTE: for 64bit coordinates the world coordinates do not fully exploit the coordinate
// range but only as much as can represented exactly by double (64bit) values.
template <>
inline int64_t box_world_min<int64_t> () { return -(int64_t (1) << 53); }
template <>
inline int64_t box_world_max<int64_t> () { return (int64_t (1) << 53); }
/**
* @brief A box class
*
@ -134,7 +149,7 @@ struct DB_PUBLIC_TEMPLATE box
*/
static box world ()
{
return box (std::numeric_limits<C>::min (), std::numeric_limits<C>::min (), std::numeric_limits<C>::max (), std::numeric_limits<C>::max ());
return box (box_world_min<C> (), box_world_min<C> (), box_world_max<C> (), box_world_max<C> ());
}
/**

View File

@ -245,3 +245,15 @@ TEST(13)
EXPECT_EQ (b.perimeter (), 8000000000.0);
}
TEST(14)
{
// world, specifically with 64bit coordinates and
// transfer via double coordinates
db::Box b = db::Box::world ();
EXPECT_EQ (b == db::Box::world (), true);
db::ICplxTrans t;
EXPECT_EQ (t * b == db::Box::world (), true);
EXPECT_EQ (t.inverted () * b == db::Box::world (), true);
}

View File

@ -1263,7 +1263,11 @@ TEST(21)
#if !defined(_MSC_VER)
ms.clear ();
poly.mem_stat (&ms, db::MemStatistics::None, 0);
#if defined(HAVE_64BIT_COORD)
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+116);
#else
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+68);
#endif
#endif
}
@ -1277,7 +1281,11 @@ TEST(21)
#if !defined(_MSC_VER)
ms.clear ();
poly.mem_stat (&ms, db::MemStatistics::None, 0);
#if defined(HAVE_64BIT_COORD)
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+84);
#else
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+52);
#endif
#endif
}
{

View File

@ -3185,19 +3185,35 @@ TEST(21)
s = shapes.begin_touching (db::Box (-500, -500, 500, 500), db::ShapeIterator::All);
size_t qid = s.quad_id ();
EXPECT_EQ (qid != 0, true);
#if defined(HAVE_64BIT_COORD)
EXPECT_EQ (s.quad_box ().to_string (), "(0,0;9007199254740992,9007199254740992)");
#else
EXPECT_EQ (s.quad_box ().to_string (), "(0,0;2147483647,2147483647)");
#endif
EXPECT_EQ (s->to_string (), "box (100,100;200,200)");
++s;
EXPECT_EQ (qid == s.quad_id (), true);
#if defined(HAVE_64BIT_COORD)
EXPECT_EQ (s.quad_box ().to_string (), "(0,0;9007199254740992,9007199254740992)");
#else
EXPECT_EQ (s.quad_box ().to_string (), "(0,0;2147483647,2147483647)");
#endif
EXPECT_EQ (s->to_string (), "box (100,100;200,200)");
s.skip_quad ();
EXPECT_EQ (qid != s.quad_id (), true);
#if defined(HAVE_64BIT_COORD)
EXPECT_EQ (s.quad_box ().to_string (), "(-9007199254740992,0;0,9007199254740992)");
#else
EXPECT_EQ (s.quad_box ().to_string (), "(-2147483648,0;0,2147483647)");
#endif
EXPECT_EQ (s->to_string (), "box (-200,100;-100,200)");
s.skip_quad ();
EXPECT_EQ (qid != s.quad_id (), true);
#if defined(HAVE_64BIT_COORD)
EXPECT_EQ (s.quad_box ().to_string (), "(0,-9007199254740992;9007199254740992,0)");
#else
EXPECT_EQ (s.quad_box ().to_string (), "(0,-2147483648;2147483647,0)");
#endif
EXPECT_EQ (s->to_string (), "box (100,-200;200,-100)");
s.skip_quad ();
EXPECT_EQ (s.at_end (), true);

View File

@ -1335,8 +1335,13 @@ TEST(116)
const char *expected =
"set props {\n"
#if defined(HAVE_64BIT_COORD)
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
#else
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
#endif
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {17 {17value}}\n"
@ -1439,8 +1444,13 @@ TEST(116)
const char *expected =
"set props {\n"
#if defined(HAVE_64BIT_COORD)
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
#else
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
#endif
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
@ -1499,8 +1509,13 @@ TEST(116)
const char *expected =
"set props {\n"
#if defined(HAVE_64BIT_COORD)
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
#else
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
#endif
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
@ -1561,8 +1576,13 @@ TEST(116)
const char *expected =
"set props {\n"
#if defined(HAVE_64BIT_COORD)
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
#else
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
#endif
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {{name} {117}}\n"
@ -1617,8 +1637,13 @@ TEST(116)
const char *expected =
"set props {\n"
#if defined(HAVE_64BIT_COORD)
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
#else
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
#endif
" {{S_TOP_CELL} {$1}}\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
@ -1668,8 +1693,13 @@ TEST(116)
const char *expected =
"set props {\n"
#if defined(HAVE_64BIT_COORD)
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
#else
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
#endif
" {{S_TOP_CELL} {$2}}\n"
" {17 {17value}}\n"
" {{name} {117}}\n"