Fixed some issues with long int emulation. Using long int as substitute for __int128

This commit is contained in:
Matthias Koefferlein 2018-07-24 22:08:30 +02:00
parent 7191e4faa9
commit c9859b4f8f
2 changed files with 39 additions and 15 deletions

View File

@ -22,6 +22,7 @@
#include "dbEdge.h" #include "dbEdge.h"
#include "tlLongInt.h"
namespace db namespace db
{ {
@ -39,12 +40,19 @@ inline C gcd (C a, C b)
return a; 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<db::Coord>::area_type b, db::coord_traits<db::Coord>::area_type d) db::Coord div_exact (db::Coord a, db::coord_traits<db::Coord>::area_type b, db::coord_traits<db::Coord>::area_type d)
{ {
if (a < 0) { 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 { } 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));
} }
} }

View File

@ -93,14 +93,19 @@ public:
template <class T> template <class T>
operator T () const operator T () const
{ {
T t = 0;
unsigned int tbits = sizeof (T) * 8; unsigned int tbits = sizeof (T) * 8;
T t = 0;
for (int i = N; i > 0 && tbits > 0; ) { if (tbits <= bits) {
--i; t = T (b[0]);
t <<= bits; } else {
t |= b[i]; unsigned int i = sizeof (T) / sizeof (B);
tbits -= bits; for ( ; i > 0 && tbits > 0; ) {
--i;
t <<= bits;
t |= b[i];
tbits -= bits;
}
} }
return t; return t;
@ -734,9 +739,15 @@ public:
template <class T> template <class T>
long_int (T t) long_int (T t)
{ {
unsigned int tbits = sizeof (T) * 8;
for (unsigned int i = 0; i < N; ++i) { for (unsigned int i = 0; i < N; ++i) {
long_uint<N, B, BI>::b[i] = B (t); long_uint<N, B, BI>::b[i] = B (t);
t >>= long_uint<N, B, BI>::bits; if (tbits <= long_uint<N, B, BI>::bits) {
t = (t < 0 ? ~B (0) : 0);
} else {
t >>= long_uint<N, B, BI>::bits;
}
} }
} }
@ -748,14 +759,19 @@ public:
template <class T> template <class T>
operator T () const operator T () const
{ {
T t = is_neg () ? -1 : 0;
unsigned int tbits = sizeof (T) * 8; unsigned int tbits = sizeof (T) * 8;
T t = 0;
for (int i = N; i > 0 && tbits > 0; ) { if (tbits <= long_uint<N, B, BI>::bits) {
--i; t = T (long_uint<N, B, BI>::b[0]);
t <<= long_uint<N, B, BI>::bits; } else {
t |= long_uint<N, B, BI>::b[i]; unsigned int i = sizeof (T) / sizeof (B);
tbits -= long_uint<N, B, BI>::bits; for ( ; i > 0 && tbits > 0; ) {
--i;
t <<= long_uint<N, B, BI>::bits;
t |= long_uint<N, B, BI>::b[i];
tbits -= long_uint<N, B, BI>::bits;
}
} }
return t; return t;