mirror of https://github.com/KLayout/klayout.git
More consistent 64bit coordinate support
This commit is contained in:
parent
390a5c11a8
commit
a2ba300bd7
|
|
@ -24,44 +24,6 @@
|
|||
|
||||
#include "tlInt128Support.h"
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
std::string
|
||||
int128_to_string (__int128 x)
|
||||
{
|
||||
std::string r;
|
||||
|
||||
// this is the max. power of 10 that can be represented with __int128
|
||||
__int128 m = (unsigned long long) 0x4b3b4ca85a86c47a;
|
||||
m <<= 64;
|
||||
m |= (unsigned long long) 0x98a224000000000;
|
||||
|
||||
if (x < 0) {
|
||||
r = "-";
|
||||
x = -x;
|
||||
} else if (x == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
while (m > 1) {
|
||||
int d = 0;
|
||||
while (x >= m) {
|
||||
d += 1;
|
||||
x -= m;
|
||||
}
|
||||
if (d > 0 || !first) {
|
||||
r += char ('0' + d);
|
||||
first = false;
|
||||
}
|
||||
m /= 10;
|
||||
}
|
||||
|
||||
r += char('0' + int(x));
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
// .. nothing yet ..
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,27 +26,27 @@
|
|||
#if defined(HAVE_64BIT_COORD)
|
||||
|
||||
#include "tlCommon.h"
|
||||
#include "tlString.h"
|
||||
#include <inttypes.h>
|
||||
#include <ostream>
|
||||
|
||||
namespace tl
|
||||
{
|
||||
TL_PUBLIC std::string int128_to_string (__int128 x);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
#if !defined(__GLIBCXX_BITSIZE_INT_N_0) || __GLIBCXX_BITSIZE_INT_N_0 != 128
|
||||
|
||||
// Provide an implementation for abs(__int128_t) if there isn't one
|
||||
inline __int128 abs (__int128 x)
|
||||
{
|
||||
return x < 0 ? -x : x;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Provide ostream serialization for 128bit values
|
||||
inline std::ostream &operator<< (std::ostream &os, __int128 x)
|
||||
{
|
||||
os << tl::int128_to_string (x);
|
||||
os << tl::to_string (x);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -232,29 +232,52 @@ tl::to_string (const unsigned long long &d)
|
|||
}
|
||||
|
||||
#if defined(HAVE_64BIT_COORD)
|
||||
|
||||
template <>
|
||||
std::string
|
||||
tl::to_string (const __int128 &d)
|
||||
{
|
||||
if (d < 0 ) {
|
||||
return "-" + tl::to_string(static_cast<unsigned __int128>(-d));
|
||||
return "-" + tl::to_string(static_cast<unsigned __int128> (-d));
|
||||
} else {
|
||||
return tl::to_string(static_cast<unsigned __int128>(d));
|
||||
return tl::to_string(static_cast<unsigned __int128> (d));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string
|
||||
tl::to_string (const unsigned __int128 &d)
|
||||
tl::to_string (const unsigned __int128 &_x)
|
||||
{
|
||||
if (static_cast<uint64_t>(d) == d) {
|
||||
return tl::to_string(static_cast<uint64_t>(d));
|
||||
std::string r;
|
||||
unsigned __int128 x = _x;
|
||||
|
||||
// this is the max. power of 10 that can be represented with __int128
|
||||
unsigned __int128 m = (unsigned long long) 0x4b3b4ca85a86c47a;
|
||||
m <<= 64;
|
||||
m |= (unsigned long long) 0x98a224000000000;
|
||||
|
||||
if (x == 0) {
|
||||
return "0";
|
||||
}
|
||||
std::ostringstream os;
|
||||
os.imbue (c_locale);
|
||||
os << "0x" << std::hex << static_cast<uint64_t> (d>>64) << static_cast<uint64_t> (d);
|
||||
return os.str ();
|
||||
|
||||
bool first = true;
|
||||
while (m > 1) {
|
||||
int d = 0;
|
||||
while (x >= m) {
|
||||
d += 1;
|
||||
x -= m;
|
||||
}
|
||||
if (d > 0 || !first) {
|
||||
r += char ('0' + d);
|
||||
first = false;
|
||||
}
|
||||
m /= 10;
|
||||
}
|
||||
|
||||
r += char('0' + int(x));
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
|
|
|
|||
|
|
@ -29,19 +29,34 @@
|
|||
|
||||
TEST(1)
|
||||
{
|
||||
EXPECT_EQ (tl::int128_to_string (__int128 (0)), "0");
|
||||
EXPECT_EQ (tl::int128_to_string (__int128 (42)), "42");
|
||||
EXPECT_EQ (tl::int128_to_string (__int128 (-42)), "-42");
|
||||
EXPECT_EQ (tl::to_string (__int128 (0)), "0");
|
||||
EXPECT_EQ (tl::to_string (__int128 (42)), "42");
|
||||
EXPECT_EQ (tl::to_string (__int128 (-42)), "-42");
|
||||
|
||||
__int128 x = 1;
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
x *= 10;
|
||||
}
|
||||
|
||||
EXPECT_EQ (tl::int128_to_string (x), "1000000000000000000000000000000");
|
||||
EXPECT_EQ (tl::int128_to_string (-x), "-1000000000000000000000000000000");
|
||||
EXPECT_EQ (tl::int128_to_string (x + 1), "1000000000000000000000000000001");
|
||||
EXPECT_EQ (tl::int128_to_string (x - 1), "999999999999999999999999999999");
|
||||
EXPECT_EQ (tl::to_string (x), "1000000000000000000000000000000");
|
||||
EXPECT_EQ (tl::to_string (-x), "-1000000000000000000000000000000");
|
||||
EXPECT_EQ (tl::to_string (x + 1), "1000000000000000000000000000001");
|
||||
EXPECT_EQ (tl::to_string (x - 1), "999999999999999999999999999999");
|
||||
}
|
||||
|
||||
TEST(2)
|
||||
{
|
||||
EXPECT_EQ (tl::to_string ((unsigned __int128) 0), "0");
|
||||
EXPECT_EQ (tl::to_string ((unsigned __int128) 42), "42");
|
||||
|
||||
unsigned __int128 x = 1;
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
x *= 10;
|
||||
}
|
||||
|
||||
EXPECT_EQ (tl::to_string (x), "1000000000000000000000000000000");
|
||||
EXPECT_EQ (tl::to_string (x + 1), "1000000000000000000000000000001");
|
||||
EXPECT_EQ (tl::to_string (x - 1), "999999999999999999999999999999");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue