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 "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<db::Coord>::area_type b, db::coord_traits<db::Coord>::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));
}
}

View File

@ -93,14 +93,19 @@ public:
template <class T>
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 <class T>
long_int (T t)
{
unsigned int tbits = sizeof (T) * 8;
for (unsigned int i = 0; i < N; ++i) {
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>
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<N, B, BI>::bits;
t |= long_uint<N, B, BI>::b[i];
tbits -= long_uint<N, B, BI>::bits;
if (tbits <= long_uint<N, B, BI>::bits) {
t = T (long_uint<N, B, BI>::b[0]);
} else {
unsigned int i = sizeof (T) / sizeof (B);
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;