diff --git a/src/db/db/dbEdge.cc b/src/db/db/dbEdge.cc index 5b3e1c7ae..f6ff11e91 100644 --- a/src/db/db/dbEdge.cc +++ b/src/db/db/dbEdge.cc @@ -22,6 +22,7 @@ #include "dbEdge.h" +#include "tlLongInt.h" namespace db { @@ -39,12 +40,19 @@ inline C gcd (C a, C b) return a; } +#if defined(__SIZEOF_INT128__) +typedef __int128 a2_type; +#else +// fallback to long_int in case the __int128 isn't defined +typedef tl::long_int<4, uint32_t, uint64_t> a2_type; +#endif + db::Coord div_exact (db::Coord a, db::coord_traits::area_type b, db::coord_traits::area_type d) { if (a < 0) { - return -db::Coord ((__int128 (-a) * __int128 (b) + __int128 (d / 2)) / __int128 (d)); + return -db::Coord ((a2_type (-a) * a2_type (b) + a2_type (d / 2)) / a2_type (d)); } else { - return db::Coord ((__int128 (a) * __int128 (b) + __int128 ((d - 1) / 2)) / __int128 (d)); + return db::Coord ((a2_type (a) * a2_type (b) + a2_type ((d - 1) / 2)) / a2_type (d)); } } diff --git a/src/tl/tl/tlLongInt.h b/src/tl/tl/tlLongInt.h index 9035bedc8..8068d79cb 100644 --- a/src/tl/tl/tlLongInt.h +++ b/src/tl/tl/tlLongInt.h @@ -93,14 +93,19 @@ public: template operator T () const { - T t = 0; unsigned int tbits = sizeof (T) * 8; + T t = 0; - for (int i = N; i > 0 && tbits > 0; ) { - --i; - t <<= bits; - t |= b[i]; - tbits -= bits; + if (tbits <= bits) { + t = T (b[0]); + } else { + unsigned int i = sizeof (T) / sizeof (B); + for ( ; i > 0 && tbits > 0; ) { + --i; + t <<= bits; + t |= b[i]; + tbits -= bits; + } } return t; @@ -734,9 +739,15 @@ public: template long_int (T t) { + unsigned int tbits = sizeof (T) * 8; + for (unsigned int i = 0; i < N; ++i) { long_uint::b[i] = B (t); - t >>= long_uint::bits; + if (tbits <= long_uint::bits) { + t = (t < 0 ? ~B (0) : 0); + } else { + t >>= long_uint::bits; + } } } @@ -748,14 +759,19 @@ public: template operator T () const { - T t = is_neg () ? -1 : 0; unsigned int tbits = sizeof (T) * 8; + T t = 0; - for (int i = N; i > 0 && tbits > 0; ) { - --i; - t <<= long_uint::bits; - t |= long_uint::b[i]; - tbits -= long_uint::bits; + if (tbits <= long_uint::bits) { + t = T (long_uint::b[0]); + } else { + unsigned int i = sizeof (T) / sizeof (B); + for ( ; i > 0 && tbits > 0; ) { + --i; + t <<= long_uint::bits; + t |= long_uint::b[i]; + tbits -= long_uint::bits; + } } return t;