aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/int128
diff options
context:
space:
mode:
authorVlad Yaroslavlev <vladon@vladon.com>2022-02-10 16:46:23 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:23 +0300
commit706b83ed7de5a473436620367af31fc0ceecde07 (patch)
tree103305d30dec77e8f6367753367f59b3cd68f9f1 /library/cpp/int128
parent918e8a1574070d0ec733f0b76cfad8f8892ad2e5 (diff)
downloadydb-706b83ed7de5a473436620367af31fc0ceecde07.tar.gz
Restoring authorship annotation for Vlad Yaroslavlev <vladon@vladon.com>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/int128')
-rw-r--r--library/cpp/int128/README.md12
-rw-r--r--library/cpp/int128/bench/main.cpp86
-rw-r--r--library/cpp/int128/bench/ya.make26
-rw-r--r--library/cpp/int128/int128.cpp104
-rw-r--r--library/cpp/int128/int128.h2546
-rw-r--r--library/cpp/int128/int128_common.h2
-rw-r--r--library/cpp/int128/int128_util.h30
-rw-r--r--library/cpp/int128/ut/.gitignore4
-rw-r--r--library/cpp/int128/ut/i128_and_intrinsic_identity_ut.cpp1192
-rw-r--r--library/cpp/int128/ut/i128_comparison_ut.cpp286
-rw-r--r--library/cpp/int128/ut/i128_division_ut.cpp822
-rw-r--r--library/cpp/int128/ut/i128_type_traits_ut.cpp132
-rw-r--r--library/cpp/int128/ut/i128_ut.cpp20
-rw-r--r--library/cpp/int128/ut/int128_old_ut.cpp202
-rw-r--r--library/cpp/int128/ut/int128_typetraits_ut.cpp608
-rw-r--r--library/cpp/int128/ut/int128_ut.cpp104
-rw-r--r--library/cpp/int128/ut/int128_ut_helpers.cpp112
-rw-r--r--library/cpp/int128/ut/int128_ut_helpers.h28
-rw-r--r--library/cpp/int128/ut/int128_via_intrinsic_ut.cpp38
-rw-r--r--library/cpp/int128/ut/ui128_division_ut.cpp520
-rw-r--r--library/cpp/int128/ut/ya.make28
-rw-r--r--library/cpp/int128/ya.make10
22 files changed, 3456 insertions, 3456 deletions
diff --git a/library/cpp/int128/README.md b/library/cpp/int128/README.md
index e1c4dcbb78..0fa0df29c6 100644
--- a/library/cpp/int128/README.md
+++ b/library/cpp/int128/README.md
@@ -1,6 +1,6 @@
-https://st.yandex-team.ru/IGNIETFERRO-697
-
-(Объединение разрозненных по Аркадии библиотек для поддержки 128-битного целого)
-
-Идея классов ui128 / i128 в том, чтобы они работали так, как будто это компиляторные интовые типы.
-Т.е. у этих классов не должно быть публичных функций типа ui128::GetHigh(), конструкторов из нескольких параметров и так далее.
+https://st.yandex-team.ru/IGNIETFERRO-697
+
+(Объединение разрозненных по Аркадии библиотек для поддержки 128-битного целого)
+
+Идея классов ui128 / i128 в том, чтобы они работали так, как будто это компиляторные интовые типы.
+Т.е. у этих классов не должно быть публичных функций типа ui128::GetHigh(), конструкторов из нескольких параметров и так далее.
diff --git a/library/cpp/int128/bench/main.cpp b/library/cpp/int128/bench/main.cpp
index be4f8d1500..54d063cc40 100644
--- a/library/cpp/int128/bench/main.cpp
+++ b/library/cpp/int128/bench/main.cpp
@@ -1,45 +1,45 @@
#include <library/cpp/int128/int128.h>
#include <library/cpp/testing/benchmark/bench.h>
-
-#include <util/generic/xrange.h>
-#include <util/system/compiler.h>
-
-Y_CPU_BENCHMARK(LibraryDivisionUnsigned128, iface) {
- ui128 b = {0, 10'000'000};
- for (const auto i : xrange(iface.Iterations())) {
- ui128 a = i * 10'000'000;
- ui128 c = a / b;
- Y_FAKE_READ(c);
- }
-}
-
-#if defined(Y_HAVE_INT128)
-Y_CPU_BENCHMARK(IntrinsicDivisionUnsigned128, iface) {
- unsigned __int128 b = 10'000'000;
- for (const auto i : xrange(iface.Iterations())) {
- unsigned __int128 a = i * 10'000'000;
- unsigned __int128 c = a / b;
- Y_FAKE_READ(c);
- }
-}
-#endif // Y_HAVE_INT128
-
-Y_CPU_BENCHMARK(LibraryDivisionSigned128, iface) {
- i128 b = {0, 10'000'000};
- for (const auto i : xrange(iface.Iterations())) {
- i128 a = i * 10'000'000;
- i128 c = a / b;
- Y_FAKE_READ(c);
- }
-}
-
-#if defined(Y_HAVE_INT128)
-Y_CPU_BENCHMARK(IntrinsicDivisionSigned128, iface) {
- signed __int128 b = 10'000'000;
- for (const auto i : xrange(iface.Iterations())) {
- signed __int128 a = i * 10'000'000;
- signed __int128 c = a / b;
- Y_FAKE_READ(c);
- }
-}
-#endif // Y_HAVE_INT128
+
+#include <util/generic/xrange.h>
+#include <util/system/compiler.h>
+
+Y_CPU_BENCHMARK(LibraryDivisionUnsigned128, iface) {
+ ui128 b = {0, 10'000'000};
+ for (const auto i : xrange(iface.Iterations())) {
+ ui128 a = i * 10'000'000;
+ ui128 c = a / b;
+ Y_FAKE_READ(c);
+ }
+}
+
+#if defined(Y_HAVE_INT128)
+Y_CPU_BENCHMARK(IntrinsicDivisionUnsigned128, iface) {
+ unsigned __int128 b = 10'000'000;
+ for (const auto i : xrange(iface.Iterations())) {
+ unsigned __int128 a = i * 10'000'000;
+ unsigned __int128 c = a / b;
+ Y_FAKE_READ(c);
+ }
+}
+#endif // Y_HAVE_INT128
+
+Y_CPU_BENCHMARK(LibraryDivisionSigned128, iface) {
+ i128 b = {0, 10'000'000};
+ for (const auto i : xrange(iface.Iterations())) {
+ i128 a = i * 10'000'000;
+ i128 c = a / b;
+ Y_FAKE_READ(c);
+ }
+}
+
+#if defined(Y_HAVE_INT128)
+Y_CPU_BENCHMARK(IntrinsicDivisionSigned128, iface) {
+ signed __int128 b = 10'000'000;
+ for (const auto i : xrange(iface.Iterations())) {
+ signed __int128 a = i * 10'000'000;
+ signed __int128 c = a / b;
+ Y_FAKE_READ(c);
+ }
+}
+#endif // Y_HAVE_INT128
diff --git a/library/cpp/int128/bench/ya.make b/library/cpp/int128/bench/ya.make
index 4800e7883d..bcd7c2a263 100644
--- a/library/cpp/int128/bench/ya.make
+++ b/library/cpp/int128/bench/ya.make
@@ -1,15 +1,15 @@
-OWNER(
- vladon
-)
-
+OWNER(
+ vladon
+)
+
Y_BENCHMARK()
-
-SRCS(
- main.cpp
-)
-
-PEERDIR(
+
+SRCS(
+ main.cpp
+)
+
+PEERDIR(
library/cpp/int128
-)
-
-END()
+)
+
+END()
diff --git a/library/cpp/int128/int128.cpp b/library/cpp/int128/int128.cpp
index a28a389fe8..dedcd28f91 100644
--- a/library/cpp/int128/int128.cpp
+++ b/library/cpp/int128/int128.cpp
@@ -1,55 +1,55 @@
-#include "int128.h"
-
-#include <tuple>
-
-IOutputStream& operator<<(IOutputStream& out, const ui128& other) {
- // see http://stackoverflow.com/questions/4361441/c-print-a-biginteger-in-base-10
- // and http://stackoverflow.com/questions/8023414/how-to-convert-a-128-bit-integer-to-a-decimal-ascii-string-in-c
- int d[39] = {0};
- int i;
- int j;
- for (i = 63; i > -1; i--) {
- if ((other.High_ >> i) & 1)
- ++d[0];
- for (j = 0; j < 39; j++)
- d[j] *= 2;
- for (j = 0; j < 38; j++) {
- d[j + 1] += d[j] / 10;
- d[j] %= 10;
- }
- }
- for (i = 63; i > -1; i--) {
- if ((other.Low_ >> i) & 1)
- ++d[0];
- if (i > 0)
- for (j = 0; j < 39; j++)
- d[j] *= 2;
- for (j = 0; j < 38; j++) {
- d[j + 1] += d[j] / 10;
- d[j] %= 10;
- }
- }
- for (i = 38; i > 0; i--)
- if (d[i] > 0)
- break;
- for (; i > -1; i--)
- out << static_cast<char>('0' + d[i]);
-
- return out;
-}
-
-void TSerializer<ui128>::Save(IOutputStream* out, const ui128& Number) {
- ::Save(out, GetHigh(Number));
- ::Save(out, GetLow(Number));
-}
-
-void TSerializer<ui128>::Load(IInputStream* in, ui128& Number) {
- ui64 High;
- ui64 Low;
- ::Load(in, High);
- ::Load(in, Low);
- Number = ui128(High, Low);
-}
+#include "int128.h"
+
+#include <tuple>
+
+IOutputStream& operator<<(IOutputStream& out, const ui128& other) {
+ // see http://stackoverflow.com/questions/4361441/c-print-a-biginteger-in-base-10
+ // and http://stackoverflow.com/questions/8023414/how-to-convert-a-128-bit-integer-to-a-decimal-ascii-string-in-c
+ int d[39] = {0};
+ int i;
+ int j;
+ for (i = 63; i > -1; i--) {
+ if ((other.High_ >> i) & 1)
+ ++d[0];
+ for (j = 0; j < 39; j++)
+ d[j] *= 2;
+ for (j = 0; j < 38; j++) {
+ d[j + 1] += d[j] / 10;
+ d[j] %= 10;
+ }
+ }
+ for (i = 63; i > -1; i--) {
+ if ((other.Low_ >> i) & 1)
+ ++d[0];
+ if (i > 0)
+ for (j = 0; j < 39; j++)
+ d[j] *= 2;
+ for (j = 0; j < 38; j++) {
+ d[j + 1] += d[j] / 10;
+ d[j] %= 10;
+ }
+ }
+ for (i = 38; i > 0; i--)
+ if (d[i] > 0)
+ break;
+ for (; i > -1; i--)
+ out << static_cast<char>('0' + d[i]);
+
+ return out;
+}
+
+void TSerializer<ui128>::Save(IOutputStream* out, const ui128& Number) {
+ ::Save(out, GetHigh(Number));
+ ::Save(out, GetLow(Number));
+}
+
+void TSerializer<ui128>::Load(IInputStream* in, ui128& Number) {
+ ui64 High;
+ ui64 Low;
+ ::Load(in, High);
+ ::Load(in, Low);
+ Number = ui128(High, Low);
+}
IOutputStream& operator<<(IOutputStream& out, const i128& other)
{
diff --git a/library/cpp/int128/int128.h b/library/cpp/int128/int128.h
index f1121fc0c6..e6345f4f12 100644
--- a/library/cpp/int128/int128.h
+++ b/library/cpp/int128/int128.h
@@ -1,1278 +1,1278 @@
-#pragma once
-
-#include "int128_util.h"
-
-#include <util/generic/bitops.h>
-#include <util/system/compiler.h>
-#include <util/system/defaults.h>
-#include <util/stream/output.h>
-#include <util/string/cast.h>
-#include <util/string/builder.h>
-#include <util/str_stl.h>
-#include <util/ysaveload.h>
-
-#include <cfenv>
-#include <climits>
-#include <cmath>
-#include <limits>
-#include <type_traits>
-
-#if !defined(_little_endian_) && !defined(_big_endian_)
- static_assert(false, "Platform endianness is not supported");
-#endif
-
-template <bool IsSigned>
-class TInteger128 {
-public:
- TInteger128() noexcept = default;
-
-#if defined(_little_endian_)
- constexpr TInteger128(const ui64 high, const ui64 low) noexcept
- : Low_(low)
- , High_(high)
- {
- }
-#elif defined(_big_endian_)
- constexpr TInteger128(const ui64 high, const ui64 low) noexcept
- : High_(high)
- , Low_(low)
- {
- }
-#endif
-
- constexpr TInteger128(const TInteger128<!IsSigned> other) noexcept
- : TInteger128{GetHigh(other), GetLow(other)}
- {
- }
-
-#if defined(_little_endian_)
- constexpr TInteger128(const char other) noexcept
- : Low_{static_cast<ui64>(other)}
- , High_{0}
- {
- }
-
- constexpr TInteger128(const ui8 other) noexcept
- : Low_{other}
- , High_{0}
- {
- }
-
- constexpr TInteger128(const ui16 other) noexcept
- : Low_{other}
- , High_{0}
- {
- }
-
- constexpr TInteger128(const ui32 other) noexcept
- : Low_{other}
- , High_{0}
- {
- }
-
- constexpr TInteger128(const ui64 other) noexcept
- : Low_{other}
- , High_{0}
- {
- }
-
-#if defined(Y_HAVE_INT128)
- constexpr TInteger128(const unsigned __int128 other) noexcept
- : Low_{static_cast<ui64>(other & ~ui64{0})}
- , High_{static_cast<ui64>(other >> 64)}
- {
- }
-#endif
-
- constexpr TInteger128(const i8 other) noexcept
- : Low_{static_cast<ui64>(other)}
- , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
- {
- }
-
- constexpr TInteger128(const i16 other) noexcept
- : Low_{static_cast<ui64>(other)}
- , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
- {
- }
-
- constexpr TInteger128(const i32 other) noexcept
- : Low_(static_cast<ui64>(other))
- , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
- {
- }
-
- constexpr TInteger128(const i64 other) noexcept
- : Low_(static_cast<ui64>(other))
- , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
- {
- }
-
-#if defined(Y_HAVE_INT128)
- template <bool IsSigned2 = IsSigned, std::enable_if_t<!IsSigned2, bool> = false>
- constexpr TInteger128(const signed __int128 other) noexcept
- : Low_{static_cast<ui64>(other & ~ui64{0})}
- , High_{static_cast<ui64>(static_cast<unsigned __int128>(other) >> 64)}
- {
- }
-
- template <bool IsSigned2 = IsSigned, typename std::enable_if_t<IsSigned2, bool> = false>
- constexpr TInteger128(const signed __int128 other) noexcept
- : Low_{static_cast<ui64>(other & ~ui64(0))}
- , High_{static_cast<ui64>(other >> 64)}
- {
- }
-#endif
-
-#elif defined(_big_endian_)
- static_assert(false, "Big-endian will be later");
-#endif // _little_endian_ or _big_endian_
-
- constexpr TInteger128& operator=(const char other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const ui8 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const ui16 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const ui32 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const ui64 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
-#if defined(Y_HAVE_INT128)
- constexpr TInteger128& operator=(const unsigned __int128 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-#endif
-
- constexpr TInteger128& operator=(const i8 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const i16 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const i32 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
- constexpr TInteger128& operator=(const i64 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-
-#if defined(Y_HAVE_INT128)
- constexpr TInteger128& operator=(const signed __int128 other) noexcept {
- *this = TInteger128{other};
- return *this;
- }
-#endif // Y_HAVE_INT128
-
- constexpr TInteger128& operator+=(const TInteger128 other) noexcept {
- return *this = *this + other;
- }
-
- constexpr TInteger128& operator-=(const TInteger128 other) noexcept {
- return *this = *this - other;
- }
-
- constexpr TInteger128& operator*=(const TInteger128 other) noexcept {
- return *this = *this * other;
- }
-
- constexpr TInteger128& operator&=(const TInteger128 other) noexcept {
- return *this = *this & other;
- }
-
- constexpr TInteger128& operator^=(const TInteger128 other) noexcept {
+#pragma once
+
+#include "int128_util.h"
+
+#include <util/generic/bitops.h>
+#include <util/system/compiler.h>
+#include <util/system/defaults.h>
+#include <util/stream/output.h>
+#include <util/string/cast.h>
+#include <util/string/builder.h>
+#include <util/str_stl.h>
+#include <util/ysaveload.h>
+
+#include <cfenv>
+#include <climits>
+#include <cmath>
+#include <limits>
+#include <type_traits>
+
+#if !defined(_little_endian_) && !defined(_big_endian_)
+ static_assert(false, "Platform endianness is not supported");
+#endif
+
+template <bool IsSigned>
+class TInteger128 {
+public:
+ TInteger128() noexcept = default;
+
+#if defined(_little_endian_)
+ constexpr TInteger128(const ui64 high, const ui64 low) noexcept
+ : Low_(low)
+ , High_(high)
+ {
+ }
+#elif defined(_big_endian_)
+ constexpr TInteger128(const ui64 high, const ui64 low) noexcept
+ : High_(high)
+ , Low_(low)
+ {
+ }
+#endif
+
+ constexpr TInteger128(const TInteger128<!IsSigned> other) noexcept
+ : TInteger128{GetHigh(other), GetLow(other)}
+ {
+ }
+
+#if defined(_little_endian_)
+ constexpr TInteger128(const char other) noexcept
+ : Low_{static_cast<ui64>(other)}
+ , High_{0}
+ {
+ }
+
+ constexpr TInteger128(const ui8 other) noexcept
+ : Low_{other}
+ , High_{0}
+ {
+ }
+
+ constexpr TInteger128(const ui16 other) noexcept
+ : Low_{other}
+ , High_{0}
+ {
+ }
+
+ constexpr TInteger128(const ui32 other) noexcept
+ : Low_{other}
+ , High_{0}
+ {
+ }
+
+ constexpr TInteger128(const ui64 other) noexcept
+ : Low_{other}
+ , High_{0}
+ {
+ }
+
+#if defined(Y_HAVE_INT128)
+ constexpr TInteger128(const unsigned __int128 other) noexcept
+ : Low_{static_cast<ui64>(other & ~ui64{0})}
+ , High_{static_cast<ui64>(other >> 64)}
+ {
+ }
+#endif
+
+ constexpr TInteger128(const i8 other) noexcept
+ : Low_{static_cast<ui64>(other)}
+ , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
+ {
+ }
+
+ constexpr TInteger128(const i16 other) noexcept
+ : Low_{static_cast<ui64>(other)}
+ , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
+ {
+ }
+
+ constexpr TInteger128(const i32 other) noexcept
+ : Low_(static_cast<ui64>(other))
+ , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
+ {
+ }
+
+ constexpr TInteger128(const i64 other) noexcept
+ : Low_(static_cast<ui64>(other))
+ , High_{other < 0 ? std::numeric_limits<ui64>::max() : 0}
+ {
+ }
+
+#if defined(Y_HAVE_INT128)
+ template <bool IsSigned2 = IsSigned, std::enable_if_t<!IsSigned2, bool> = false>
+ constexpr TInteger128(const signed __int128 other) noexcept
+ : Low_{static_cast<ui64>(other & ~ui64{0})}
+ , High_{static_cast<ui64>(static_cast<unsigned __int128>(other) >> 64)}
+ {
+ }
+
+ template <bool IsSigned2 = IsSigned, typename std::enable_if_t<IsSigned2, bool> = false>
+ constexpr TInteger128(const signed __int128 other) noexcept
+ : Low_{static_cast<ui64>(other & ~ui64(0))}
+ , High_{static_cast<ui64>(other >> 64)}
+ {
+ }
+#endif
+
+#elif defined(_big_endian_)
+ static_assert(false, "Big-endian will be later");
+#endif // _little_endian_ or _big_endian_
+
+ constexpr TInteger128& operator=(const char other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const ui8 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const ui16 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const ui32 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const ui64 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+#if defined(Y_HAVE_INT128)
+ constexpr TInteger128& operator=(const unsigned __int128 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+#endif
+
+ constexpr TInteger128& operator=(const i8 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const i16 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const i32 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+ constexpr TInteger128& operator=(const i64 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+
+#if defined(Y_HAVE_INT128)
+ constexpr TInteger128& operator=(const signed __int128 other) noexcept {
+ *this = TInteger128{other};
+ return *this;
+ }
+#endif // Y_HAVE_INT128
+
+ constexpr TInteger128& operator+=(const TInteger128 other) noexcept {
+ return *this = *this + other;
+ }
+
+ constexpr TInteger128& operator-=(const TInteger128 other) noexcept {
+ return *this = *this - other;
+ }
+
+ constexpr TInteger128& operator*=(const TInteger128 other) noexcept {
+ return *this = *this * other;
+ }
+
+ constexpr TInteger128& operator&=(const TInteger128 other) noexcept {
+ return *this = *this & other;
+ }
+
+ constexpr TInteger128& operator^=(const TInteger128 other) noexcept {
return *this = *this ^ other;
- }
-
- constexpr TInteger128& operator|=(const TInteger128 other) noexcept {
- return *this = *this | other;
- }
-
- constexpr TInteger128& operator<<=(int n) noexcept {
- *this = *this << n;
- return *this;
- }
-
- constexpr TInteger128& operator>>=(int n) noexcept {
- *this = *this >> n;
- return *this;
- }
-
- constexpr TInteger128& operator++() noexcept {
- *this += 1;
- return *this;
- }
-
- constexpr TInteger128 operator++(int) noexcept {
- const TInteger128 ret{*this};
- this->operator++();
- return ret;
- }
-
- constexpr TInteger128& operator--() noexcept {
- *this -= 1;
- return *this;
- }
-
- constexpr TInteger128 operator--(int) noexcept {
- const TInteger128 ret{*this};
- this->operator--();
- return ret;
- }
-
- explicit constexpr operator bool() const noexcept {
- return Low_ || High_;
- }
-
- explicit constexpr operator char() const noexcept {
- return static_cast<char>(Low_);
- }
-
- explicit constexpr operator ui8() const noexcept {
- return static_cast<ui8>(Low_);
- }
-
- explicit constexpr operator i8() const noexcept {
- return static_cast<i8>(Low_);
- }
-
- explicit constexpr operator ui16() const noexcept {
- return static_cast<ui16>(Low_);
- }
-
- explicit constexpr operator i16() const noexcept {
- return static_cast<i16>(Low_);
- }
-
- explicit constexpr operator ui32() const noexcept {
- return static_cast<ui32>(Low_);
- }
-
- explicit constexpr operator i32() const noexcept {
- return static_cast<i32>(Low_);
- }
-
- explicit constexpr operator ui64() const noexcept {
- return static_cast<ui64>(Low_);
- }
-
- explicit constexpr operator i64() const noexcept {
- return static_cast<i64>(Low_);
- }
-
-#if defined(Y_HAVE_INT128)
- explicit constexpr operator unsigned __int128() const noexcept {
- return (static_cast<unsigned __int128>(High_) << 64) + Low_;
- }
-
- explicit constexpr operator signed __int128() const noexcept {
- return (static_cast<__int128>(High_) << 64) + Low_;
- }
-#endif
-
-private:
-#if defined(_little_endian_)
- ui64 Low_;
- ui64 High_;
-#elif defined(_big_endian_)
- ui64 High_;
- ui64 Low_;
-#endif
- template <bool IsSigned2>
- friend constexpr ui64 GetHigh(TInteger128<IsSigned2> value) noexcept;
-
- template <bool IsSigned2>
- friend constexpr ui64 GetLow(TInteger128<IsSigned2> value) noexcept;
-
- friend IOutputStream& operator<<(IOutputStream& out, const TInteger128& other);
-}; // class TInteger128
-
-using ui128 = TInteger128<false>;
-using i128 = TInteger128<true>;
-
-constexpr ui128 operator+(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator+( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator-(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator-( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator-(ui128 num) noexcept;
-constexpr i128 operator-( i128 num) noexcept;
-constexpr ui128 operator*(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator*( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator/(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator/( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator%(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator%( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator|(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator|( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator&(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator&( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator^(ui128 lhs, ui128 rhs) noexcept;
-constexpr i128 operator^( i128 lhs, i128 rhs) noexcept;
-constexpr ui128 operator<<(ui128 lhs, int n) noexcept;
-constexpr i128 operator<<( i128 lhs, int n) noexcept;
-constexpr ui128 operator>>(ui128 lhs, int n) noexcept;
-constexpr i128 operator>>( i128 lhs, int n) noexcept;
-
-template <bool IsSigned>
-size_t MostSignificantBit(const TInteger128<IsSigned> v);
-
-namespace std {
- //// type traits
- template <bool IsSigned>
- struct is_integral<TInteger128<IsSigned>> : public std::true_type{};
-
- template <bool IsSigned>
- struct is_class<TInteger128<IsSigned>> : public std::false_type{};
-
- template <>
- struct is_signed<ui128> : public std::false_type{};
-
- template <>
- struct is_signed<i128> : public std::true_type{};
-}
-
-template <bool IsSigned>
-constexpr ui64 GetHigh(const TInteger128<IsSigned> value) noexcept {
- return value.High_;
-}
-
-template <bool IsSigned>
-constexpr ui64 GetLow(const TInteger128<IsSigned> value) noexcept {
- return value.Low_;
-}
-
-template <class T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, i128>>* = nullptr>
-constexpr ui128 operator-(const ui128 lhs, const T rhs) noexcept {
- return lhs - static_cast<ui128>(rhs);
-}
-
-template <class T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, ui128>>* = nullptr>
-constexpr ui128 operator-(const i128 lhs, const T rhs) noexcept {
- return static_cast<ui128>(lhs) - rhs;
-}
-
-// specialize std templates
-namespace std {
- // numeric limits
- // see full list at https://en.cppreference.com/w/cpp/types/numeric_limits
- template <bool IsSigned>
- struct numeric_limits<TInteger128<IsSigned>> {
- static constexpr bool is_specialized = true;
- static constexpr bool is_signed = IsSigned;
- static constexpr bool is_integer = true;
- static constexpr bool is_exact = true;
- static constexpr bool has_infinity = false;
- static constexpr bool has_quiet_NAN = false;
- static constexpr bool has_signaling_NAN = false;
- static constexpr float_denorm_style has_denorm = std::denorm_absent;
- static constexpr bool has_denorm_loss = false;
- static constexpr float_round_style round_style = std::round_toward_zero;
- static constexpr bool is_iec559 = false;
- static constexpr bool is_bounded = true;
- static constexpr bool is_modulo = true;
- static constexpr int digits = CHAR_BIT * sizeof(ui128) - (IsSigned ? 1 : 0);
- static constexpr int digits10 = 38; // std::numeric_limits<ui128>::digits * std::log10(2);
- static constexpr int max_digits10 = 0;
- static constexpr int radix = 2;
- static constexpr int min_exponent = 0;
- static constexpr int min_exponent10 = 0;
- static constexpr int max_exponent = 0;
- static constexpr int max_exponent10 = 0;
- static constexpr bool traps = std::numeric_limits<ui64>::traps; // same as of any other ui*
- static constexpr bool tinyness_before = false;
-
- static constexpr TInteger128<IsSigned> min() noexcept {
- if constexpr (IsSigned) {
- return TInteger128<IsSigned>{
- static_cast<ui64>(std::numeric_limits<i64>::min()),
- 0
- };
- }
- else {
- return 0;
- }
- }
-
- static constexpr TInteger128<IsSigned> lowest() noexcept {
- return min();
- }
-
- static constexpr TInteger128<IsSigned> max() noexcept {
- if constexpr (IsSigned) {
- return TInteger128<IsSigned>{
- static_cast<ui64>(std::numeric_limits<i64>::max()),
- std::numeric_limits<ui64>::max()
- };
- }
- else {
- return TInteger128<IsSigned>{
- std::numeric_limits<ui64>::max(),
- std::numeric_limits<ui64>::max()
- };
- }
- }
-
- static constexpr TInteger128<IsSigned> epsilon() noexcept {
- return 0;
- }
-
- static constexpr TInteger128<IsSigned> round_error() noexcept {
- return 0;
- }
-
- static constexpr TInteger128<IsSigned> infinity() noexcept {
- return 0;
- }
-
- static constexpr TInteger128<IsSigned> quiet_NAN() noexcept {
- return 0;
- }
-
- static constexpr TInteger128<IsSigned> signaling_NAN() noexcept {
- return 0;
- }
-
- static constexpr TInteger128<IsSigned> denorm_min() noexcept {
- return 0;
- }
- };
-
- constexpr bool signbit(const ui128 arg) noexcept {
- Y_UNUSED(arg);
- return false;
- }
-
- constexpr bool signbit(const i128 arg) noexcept {
- return GetHigh(arg) & 0x8000000000000000;
- }
-
- constexpr ui128 abs(const ui128 arg) noexcept {
- return arg;
- }
-
- constexpr i128 abs(const i128 arg) noexcept {
- return signbit(arg) ? (-arg) : arg;
- }
-}
-
-constexpr bool operator==(const ui128 lhs, const ui128 rhs) noexcept {
- return GetLow(lhs) == GetLow(rhs) && GetHigh(lhs) == GetHigh(rhs);
-}
-
-constexpr bool operator==(const i128 lhs, const i128 rhs) noexcept {
- return GetLow(lhs) == GetLow(rhs) && GetHigh(lhs) == GetHigh(rhs);
-}
-
-constexpr bool operator!=(const ui128 lhs, const ui128 rhs) noexcept {
- return !(lhs == rhs);
-}
-
-constexpr bool operator!=(const i128 lhs, const i128 rhs) noexcept {
- return !(lhs == rhs);
-}
-
-constexpr bool operator<(const ui128 lhs, const ui128 rhs) noexcept {
- if (GetHigh(lhs) != GetHigh(rhs)) {
- return GetHigh(lhs) < GetHigh(rhs);
- }
-
- return GetLow(lhs) < GetLow(rhs);
-}
-
-constexpr bool operator<(const i128 lhs, const i128 rhs) noexcept {
- if (lhs == 0 && rhs == 0) {
- return false;
- }
-
- const bool lhsIsNegative = std::signbit(lhs);
- const bool rhsIsNegative = std::signbit(rhs);
-
- if (lhsIsNegative && !rhsIsNegative) {
- return true;
- }
-
- if (!lhsIsNegative && rhsIsNegative) {
- return false;
- }
-
- // both are negative or both are positive
- if (GetHigh(lhs) != GetHigh(rhs)) {
- return GetHigh(lhs) < GetHigh(rhs);
- }
-
- return GetLow(lhs) < GetLow(rhs);
-}
-
-constexpr bool operator>(const ui128 lhs, const ui128 rhs) noexcept {
- return rhs < lhs;
-}
-
-constexpr bool operator>(const i128 lhs, const i128 rhs) noexcept {
- return rhs < lhs;
-}
-
-constexpr bool operator<=(const ui128 lhs, const ui128 rhs) noexcept {
- return !(rhs < lhs);
-}
-
-constexpr bool operator<=(const i128 lhs, const i128 rhs) noexcept {
- return !(rhs < lhs);
-}
-
-constexpr bool operator>=(const ui128 lhs, const ui128 rhs) noexcept {
- return !(lhs < rhs);
-}
-
-constexpr bool operator>=(const i128 lhs, const i128 rhs) noexcept {
- return !(lhs < rhs);
-}
-
-constexpr ui128 operator+(const ui128 lhs, const ui128 rhs) noexcept {
- const ui128 result{GetHigh(lhs) + GetHigh(rhs), GetLow(lhs) + GetLow(rhs)};
- if (GetLow(result) < GetLow(lhs)) {
- return ui128{GetHigh(result) + 1, GetLow(result)};
- }
- return result;
-}
-
-constexpr i128 operator+(const i128 lhs, const i128 rhs) noexcept {
- const i128 result{GetHigh(lhs) + GetHigh(rhs), GetLow(lhs) + GetLow(rhs)};
- if (GetLow(result) < GetLow(lhs)) {
- return i128{GetHigh(result) + 1, GetLow(result)};
- }
- return result;
-}
-
-constexpr ui128 operator-(const ui128 lhs, const ui128 rhs) noexcept {
- const ui128 result{GetHigh(lhs) - GetHigh(rhs), GetLow(lhs) - GetLow(rhs)};
- if (GetLow(result) > GetLow(lhs)) { // underflow
- return ui128{GetHigh(result) - 1, GetLow(result)};
- }
- return result;
-}
-
-constexpr i128 operator-(const i128 lhs, const i128 rhs) noexcept {
- const i128 result{GetHigh(lhs) - GetHigh(rhs), GetLow(lhs) - GetLow(rhs)};
- if (GetLow(result) > GetLow(lhs)) { // underflow
- return i128{GetHigh(result) - 1, GetLow(result)};
- }
- return result;
-}
-
-constexpr ui128 operator-(const ui128 num) noexcept {
- const ui128 result{~GetHigh(num), ~GetLow(num) + 1};
- if (GetLow(result) == 0) {
- return ui128{GetHigh(result) + 1, GetLow(result)};
- }
- return result;
-}
-
-constexpr i128 operator-(const i128 num) noexcept {
- const i128 result{~GetHigh(num), ~GetLow(num) + 1};
- if (GetLow(result) == 0) {
- return i128{GetHigh(result) + 1, GetLow(result)};
- }
- return result;
-}
-
-constexpr ui128 operator*(const ui128 lhs, const ui128 rhs) noexcept {
- if (rhs == 0) {
- return 0;
- }
- if (rhs == 1) {
- return lhs;
- }
-
- ui128 result{};
- ui128 t = rhs;
-
- for (size_t i = 0; i < 128; ++i) {
- if ((t & 1) != 0) {
- result += (lhs << i);
- }
-
- t = t >> 1;
- }
-
- return result;
-}
-
-constexpr i128 operator*(const i128 lhs, const i128 rhs) noexcept {
- if (rhs == 0) {
- return 0;
- }
- if (rhs == 1) {
- return lhs;
- }
-
- i128 result{};
- i128 t = rhs;
-
- for (size_t i = 0; i < 128; ++i) {
- if ((t & 1) != 0) {
- result += (lhs << i);
- }
-
- t = t >> 1;
- }
-
- return result;
-}
-
-namespace NPrivateInt128 {
- // NOTE: division by zero is UB and can be changed in future
- constexpr void DivMod128(const ui128 lhs, const ui128 rhs, ui128* const quo, ui128* const rem) {
- if (!quo && !rem) {
- return;
- }
-
- constexpr size_t n_udword_bits = sizeof(ui64) * CHAR_BIT;
- constexpr size_t n_utword_bits = sizeof(ui128) * CHAR_BIT;
-
- ui128 q{};
- ui128 r{};
-
- unsigned sr{};
-
- /* special cases, X is unknown, K != 0 */
- if (GetHigh(lhs) == 0)
- {
- if (GetHigh(rhs) == 0)
- {
- /* 0 X
- * ---
- * 0 X
- */
- if (rem) {
- *rem = GetLow(lhs) % GetLow(rhs);
- }
- if (quo) {
- *quo = GetLow(lhs) / GetLow(rhs);
- }
- return;
- }
- /* 0 X
- * ---
- * K X
- */
- if (rem) {
- *rem = GetLow(lhs);
- }
- if (quo) {
- *quo = 0;
- }
- return;
- }
- /* n.s.high != 0 */
- if (GetLow(rhs) == 0)
- {
- if (GetHigh(rhs) == 0)
- {
- /* K X
- * ---
- * 0 0
- */
- if (rem) {
- *rem = GetHigh(lhs) % GetLow(rhs);
- }
- if (quo) {
- *quo = GetHigh(lhs) / GetLow(rhs);
- }
- return;
- }
- /* d.s.high != 0 */
- if (GetLow(lhs) == 0)
- {
- /* K 0
- * ---
- * K 0
- */
- if (rem) {
- *rem = ui128{GetHigh(lhs) % GetHigh(rhs), 0};
- }
- if (quo) {
- *quo = GetHigh(lhs) / GetHigh(rhs);
- }
- return;
- }
- /* K K
- * ---
- * K 0
- */
- if ((GetHigh(rhs) & (GetHigh(rhs) - 1)) == 0) /* if d is a power of 2 */
- {
- if (rem) {
- *rem = ui128{GetHigh(lhs) & (GetHigh(rhs) - 1), GetLow(lhs)};
- }
- if (quo) {
- *quo = GetHigh(lhs) >> CountLeadingZeroBits(GetHigh(rhs));
- }
- return;
- }
- /* K K
- * ---
- * K 0
- */
- sr = CountLeadingZeroBits(GetHigh(rhs)) - CountLeadingZeroBits(GetHigh(lhs));
- /* 0 <= sr <= n_udword_bits - 2 or sr large */
- if (sr > n_udword_bits - 2)
- {
- if (rem) {
- *rem = lhs;
- }
- if (quo) {
- *quo = 0;
- }
- return;
- }
- ++sr;
- /* 1 <= sr <= n_udword_bits - 1 */
- /* q.all = n.all << (n_utword_bits - sr); */
- q = ui128{
- GetLow(lhs) << (n_udword_bits - sr),
- 0
- };
- r = ui128{
- GetHigh(lhs) >> sr,
- (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
- };
- }
- else /* d.s.low != 0 */
- {
- if (GetHigh(rhs) == 0)
- {
- /* K X
- * ---
- * 0 K
- */
- if ((GetLow(rhs) & (GetLow(rhs) - 1)) == 0) /* if d is a power of 2 */
- {
- if (rem) {
- *rem = ui128{0, GetLow(lhs) & (GetLow(rhs) - 1)};
- }
- if (GetLow(rhs) == 1) {
- if (quo) {
- *quo = lhs;
- }
- return;
- }
- sr = CountTrailingZeroBits(GetLow(rhs));
- if (quo) {
- *quo = ui128{
- GetHigh(lhs) >> sr,
- (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
- };
- return;
- }
- }
- /* K X
- * ---
- * 0 K
- */
- sr = 1 + n_udword_bits + CountLeadingZeroBits(GetLow(rhs))
- - CountLeadingZeroBits(GetHigh(lhs));
- /* 2 <= sr <= n_utword_bits - 1
- * q.all = n.all << (n_utword_bits - sr);
- * r.all = n.all >> sr;
- */
- if (sr == n_udword_bits)
- {
- q = ui128{GetLow(lhs), 0};
- r = ui128{0, GetHigh(lhs)};
- }
- else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
- {
- q = ui128{
- GetLow(lhs) << (n_udword_bits - sr),
- 0
- };
- r = ui128{
- GetHigh(lhs) >> sr,
- (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
- };
- }
- else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
- {
- q = ui128{
- (GetHigh(lhs) << (n_utword_bits - sr)) | (GetLow(lhs) >> (sr - n_udword_bits)),
- GetLow(lhs) << (n_utword_bits - sr)
- };
- r = ui128{
- 0,
- GetHigh(lhs) >> (sr - n_udword_bits)
- };
- }
- }
- else
- {
- /* K X
- * ---
- * K K
- */
- sr = CountLeadingZeroBits(GetHigh(rhs)) - CountLeadingZeroBits(GetHigh(lhs));
- /*0 <= sr <= n_udword_bits - 1 or sr large */
- if (sr > n_udword_bits - 1)
- {
- if (rem) {
- *rem = lhs;
- }
- if (quo) {
- *quo = 0;
- }
- return;
- }
- ++sr;
- /* 1 <= sr <= n_udword_bits
- * q.all = n.all << (n_utword_bits - sr);
- * r.all = n.all >> sr;
- */
- if (sr == n_udword_bits)
- {
- q = ui128{
- GetLow(lhs),
- 0
- };
- r = ui128{
- 0,
- GetHigh(lhs)
- };
- }
- else
- {
- r = ui128{
- GetHigh(lhs) >> sr,
- (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
- };
- q = ui128{
- GetLow(lhs) << (n_udword_bits - sr),
- 0
- };
- }
- }
- }
- /* Not a special case
- * q and r are initialized with:
- * q = n << (128 - sr);
- * r = n >> sr;
- * 1 <= sr <= 128 - 1
- */
- ui32 carry = 0;
- for (; sr > 0; --sr)
- {
- /* r:q = ((r:q) << 1) | carry */
- r = ui128{
- (GetHigh(r) << 1) | (GetLow(r) >> (n_udword_bits - 1)),
- (GetLow(r) << 1) | (GetHigh(q) >> (n_udword_bits - 1))
- };
- q = ui128{
- (GetHigh(q) << 1) | (GetLow(q) >> (n_udword_bits - 1)),
- (GetLow(q) << 1) | carry
- };
- carry = 0;
- if (r >= rhs) {
- r -= rhs;
- carry = 1;
- }
- }
- q = (q << 1) | carry;
- if (rem) {
- *rem = r;
- }
- if (quo) {
- *quo = q;
- }
- }
-
- struct TSignedDivisionResult {
- i128 Quotient;
- i128 Remainder;
- };
-
- constexpr TSignedDivisionResult Divide(i128 lhs, i128 rhs) noexcept;
-}
-
-constexpr ui128 operator/(const ui128 lhs, const ui128 rhs) noexcept {
- ui128 quotient{};
- NPrivateInt128::DivMod128(lhs, rhs, &quotient, nullptr);
- return quotient;
-}
-
-constexpr i128 operator/(const i128 lhs, const i128 rhs) noexcept {
- i128 a = std::abs(lhs);
- i128 b = std::abs(rhs);
-
- ui128 quotient{};
- NPrivateInt128::DivMod128(a, b, &quotient, nullptr);
- if (std::signbit(lhs) ^ std::signbit(rhs)) {
- quotient = -quotient;
- }
- return quotient;
-}
-
-constexpr ui128 operator%(const ui128 lhs, const ui128 rhs) noexcept {
- ui128 remainder{};
- NPrivateInt128::DivMod128(lhs, rhs, nullptr, &remainder);
- return remainder;
-}
-
-constexpr i128 operator%(const i128 lhs, const i128 rhs) noexcept {
- i128 a = std::abs(lhs);
- i128 b = std::abs(rhs);
- ui128 remainder{};
- NPrivateInt128::DivMod128(a, b, nullptr, &remainder);
- if (std::signbit(lhs)) {
- remainder = -remainder;
- }
- return remainder;
-}
-
-constexpr ui128 operator<<(const ui128 lhs, int n) noexcept {
- if (n < 64) {
- if (n != 0) {
- return
- ui128{
- (GetHigh(lhs) << n) | (GetLow(lhs) >> (64 - n)),
- GetLow(lhs) << n
- };
- }
- return lhs;
- }
- return ui128{GetLow(lhs) << (n - 64), 0};
-}
-
-constexpr ui128 operator>>(const ui128 lhs, int n) noexcept {
- if (n < 64) {
- if (n != 0) {
- return
- ui128{
- GetHigh(lhs) >> n,
- (GetLow(lhs) >> n) | (GetHigh(lhs) << (64 - n))
- };
- }
- return lhs;
- }
- return ui128{0, GetHigh(lhs) >> (n - 64)};
-}
-
-
-constexpr bool operator!(const ui128 num) noexcept {
- return !GetHigh(num) && !GetLow(num);
-}
-
-constexpr ui128 operator~(const ui128 num) noexcept {
- return ui128{~GetHigh(num), ~GetLow(num)};
-}
-
-constexpr ui128 operator|(const ui128 lhs, const ui128 rhs) noexcept {
- return ui128{GetHigh(lhs) | GetHigh(rhs), GetLow(lhs) | GetLow(rhs)};
-}
-
-constexpr ui128 operator&(const ui128 lhs, const ui128 rhs) noexcept {
- return ui128{GetHigh(lhs) & GetHigh(rhs), GetLow(lhs) & GetLow(rhs)};
-}
-
-constexpr ui128 operator^(const ui128 lhs, const ui128 rhs) noexcept {
- return ui128{GetHigh(lhs) ^ GetHigh(rhs), GetLow(lhs) ^ GetLow(rhs)};
-}
-
-
-IOutputStream& operator<<(IOutputStream& out, const ui128& other);
-
-// For THashMap
-template <>
-struct THash<ui128> {
- inline size_t operator()(const ui128& num) const {
- return THash<ui64>()(GetHigh(num)) + THash<ui64>()(GetLow(num));
- }
-};
-
-template <>
-class TSerializer<ui128> {
-public:
- static void Save(IOutputStream* out, const ui128& Number);
- static void Load(IInputStream* in, ui128& Number);
-};
-
-template <>
-inline TString ToString<ui128>(const ui128& number) {
- return TStringBuilder{} << number;
-}
-
-template <>
-inline ui128 FromStringImpl<ui128>(const char* data, size_t length) {
- if (length < 20) {
- return ui128{ FromString<ui64>(data, length) };
- } else {
- ui128 result = 0;
- const TStringBuf string(data, length);
- for (auto&& c : string) {
- if (!std::isdigit(c)) {
+ }
+
+ constexpr TInteger128& operator|=(const TInteger128 other) noexcept {
+ return *this = *this | other;
+ }
+
+ constexpr TInteger128& operator<<=(int n) noexcept {
+ *this = *this << n;
+ return *this;
+ }
+
+ constexpr TInteger128& operator>>=(int n) noexcept {
+ *this = *this >> n;
+ return *this;
+ }
+
+ constexpr TInteger128& operator++() noexcept {
+ *this += 1;
+ return *this;
+ }
+
+ constexpr TInteger128 operator++(int) noexcept {
+ const TInteger128 ret{*this};
+ this->operator++();
+ return ret;
+ }
+
+ constexpr TInteger128& operator--() noexcept {
+ *this -= 1;
+ return *this;
+ }
+
+ constexpr TInteger128 operator--(int) noexcept {
+ const TInteger128 ret{*this};
+ this->operator--();
+ return ret;
+ }
+
+ explicit constexpr operator bool() const noexcept {
+ return Low_ || High_;
+ }
+
+ explicit constexpr operator char() const noexcept {
+ return static_cast<char>(Low_);
+ }
+
+ explicit constexpr operator ui8() const noexcept {
+ return static_cast<ui8>(Low_);
+ }
+
+ explicit constexpr operator i8() const noexcept {
+ return static_cast<i8>(Low_);
+ }
+
+ explicit constexpr operator ui16() const noexcept {
+ return static_cast<ui16>(Low_);
+ }
+
+ explicit constexpr operator i16() const noexcept {
+ return static_cast<i16>(Low_);
+ }
+
+ explicit constexpr operator ui32() const noexcept {
+ return static_cast<ui32>(Low_);
+ }
+
+ explicit constexpr operator i32() const noexcept {
+ return static_cast<i32>(Low_);
+ }
+
+ explicit constexpr operator ui64() const noexcept {
+ return static_cast<ui64>(Low_);
+ }
+
+ explicit constexpr operator i64() const noexcept {
+ return static_cast<i64>(Low_);
+ }
+
+#if defined(Y_HAVE_INT128)
+ explicit constexpr operator unsigned __int128() const noexcept {
+ return (static_cast<unsigned __int128>(High_) << 64) + Low_;
+ }
+
+ explicit constexpr operator signed __int128() const noexcept {
+ return (static_cast<__int128>(High_) << 64) + Low_;
+ }
+#endif
+
+private:
+#if defined(_little_endian_)
+ ui64 Low_;
+ ui64 High_;
+#elif defined(_big_endian_)
+ ui64 High_;
+ ui64 Low_;
+#endif
+ template <bool IsSigned2>
+ friend constexpr ui64 GetHigh(TInteger128<IsSigned2> value) noexcept;
+
+ template <bool IsSigned2>
+ friend constexpr ui64 GetLow(TInteger128<IsSigned2> value) noexcept;
+
+ friend IOutputStream& operator<<(IOutputStream& out, const TInteger128& other);
+}; // class TInteger128
+
+using ui128 = TInteger128<false>;
+using i128 = TInteger128<true>;
+
+constexpr ui128 operator+(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator+( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator-(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator-( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator-(ui128 num) noexcept;
+constexpr i128 operator-( i128 num) noexcept;
+constexpr ui128 operator*(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator*( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator/(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator/( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator%(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator%( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator|(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator|( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator&(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator&( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator^(ui128 lhs, ui128 rhs) noexcept;
+constexpr i128 operator^( i128 lhs, i128 rhs) noexcept;
+constexpr ui128 operator<<(ui128 lhs, int n) noexcept;
+constexpr i128 operator<<( i128 lhs, int n) noexcept;
+constexpr ui128 operator>>(ui128 lhs, int n) noexcept;
+constexpr i128 operator>>( i128 lhs, int n) noexcept;
+
+template <bool IsSigned>
+size_t MostSignificantBit(const TInteger128<IsSigned> v);
+
+namespace std {
+ //// type traits
+ template <bool IsSigned>
+ struct is_integral<TInteger128<IsSigned>> : public std::true_type{};
+
+ template <bool IsSigned>
+ struct is_class<TInteger128<IsSigned>> : public std::false_type{};
+
+ template <>
+ struct is_signed<ui128> : public std::false_type{};
+
+ template <>
+ struct is_signed<i128> : public std::true_type{};
+}
+
+template <bool IsSigned>
+constexpr ui64 GetHigh(const TInteger128<IsSigned> value) noexcept {
+ return value.High_;
+}
+
+template <bool IsSigned>
+constexpr ui64 GetLow(const TInteger128<IsSigned> value) noexcept {
+ return value.Low_;
+}
+
+template <class T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, i128>>* = nullptr>
+constexpr ui128 operator-(const ui128 lhs, const T rhs) noexcept {
+ return lhs - static_cast<ui128>(rhs);
+}
+
+template <class T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, ui128>>* = nullptr>
+constexpr ui128 operator-(const i128 lhs, const T rhs) noexcept {
+ return static_cast<ui128>(lhs) - rhs;
+}
+
+// specialize std templates
+namespace std {
+ // numeric limits
+ // see full list at https://en.cppreference.com/w/cpp/types/numeric_limits
+ template <bool IsSigned>
+ struct numeric_limits<TInteger128<IsSigned>> {
+ static constexpr bool is_specialized = true;
+ static constexpr bool is_signed = IsSigned;
+ static constexpr bool is_integer = true;
+ static constexpr bool is_exact = true;
+ static constexpr bool has_infinity = false;
+ static constexpr bool has_quiet_NAN = false;
+ static constexpr bool has_signaling_NAN = false;
+ static constexpr float_denorm_style has_denorm = std::denorm_absent;
+ static constexpr bool has_denorm_loss = false;
+ static constexpr float_round_style round_style = std::round_toward_zero;
+ static constexpr bool is_iec559 = false;
+ static constexpr bool is_bounded = true;
+ static constexpr bool is_modulo = true;
+ static constexpr int digits = CHAR_BIT * sizeof(ui128) - (IsSigned ? 1 : 0);
+ static constexpr int digits10 = 38; // std::numeric_limits<ui128>::digits * std::log10(2);
+ static constexpr int max_digits10 = 0;
+ static constexpr int radix = 2;
+ static constexpr int min_exponent = 0;
+ static constexpr int min_exponent10 = 0;
+ static constexpr int max_exponent = 0;
+ static constexpr int max_exponent10 = 0;
+ static constexpr bool traps = std::numeric_limits<ui64>::traps; // same as of any other ui*
+ static constexpr bool tinyness_before = false;
+
+ static constexpr TInteger128<IsSigned> min() noexcept {
+ if constexpr (IsSigned) {
+ return TInteger128<IsSigned>{
+ static_cast<ui64>(std::numeric_limits<i64>::min()),
+ 0
+ };
+ }
+ else {
+ return 0;
+ }
+ }
+
+ static constexpr TInteger128<IsSigned> lowest() noexcept {
+ return min();
+ }
+
+ static constexpr TInteger128<IsSigned> max() noexcept {
+ if constexpr (IsSigned) {
+ return TInteger128<IsSigned>{
+ static_cast<ui64>(std::numeric_limits<i64>::max()),
+ std::numeric_limits<ui64>::max()
+ };
+ }
+ else {
+ return TInteger128<IsSigned>{
+ std::numeric_limits<ui64>::max(),
+ std::numeric_limits<ui64>::max()
+ };
+ }
+ }
+
+ static constexpr TInteger128<IsSigned> epsilon() noexcept {
+ return 0;
+ }
+
+ static constexpr TInteger128<IsSigned> round_error() noexcept {
+ return 0;
+ }
+
+ static constexpr TInteger128<IsSigned> infinity() noexcept {
+ return 0;
+ }
+
+ static constexpr TInteger128<IsSigned> quiet_NAN() noexcept {
+ return 0;
+ }
+
+ static constexpr TInteger128<IsSigned> signaling_NAN() noexcept {
+ return 0;
+ }
+
+ static constexpr TInteger128<IsSigned> denorm_min() noexcept {
+ return 0;
+ }
+ };
+
+ constexpr bool signbit(const ui128 arg) noexcept {
+ Y_UNUSED(arg);
+ return false;
+ }
+
+ constexpr bool signbit(const i128 arg) noexcept {
+ return GetHigh(arg) & 0x8000000000000000;
+ }
+
+ constexpr ui128 abs(const ui128 arg) noexcept {
+ return arg;
+ }
+
+ constexpr i128 abs(const i128 arg) noexcept {
+ return signbit(arg) ? (-arg) : arg;
+ }
+}
+
+constexpr bool operator==(const ui128 lhs, const ui128 rhs) noexcept {
+ return GetLow(lhs) == GetLow(rhs) && GetHigh(lhs) == GetHigh(rhs);
+}
+
+constexpr bool operator==(const i128 lhs, const i128 rhs) noexcept {
+ return GetLow(lhs) == GetLow(rhs) && GetHigh(lhs) == GetHigh(rhs);
+}
+
+constexpr bool operator!=(const ui128 lhs, const ui128 rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+constexpr bool operator!=(const i128 lhs, const i128 rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+constexpr bool operator<(const ui128 lhs, const ui128 rhs) noexcept {
+ if (GetHigh(lhs) != GetHigh(rhs)) {
+ return GetHigh(lhs) < GetHigh(rhs);
+ }
+
+ return GetLow(lhs) < GetLow(rhs);
+}
+
+constexpr bool operator<(const i128 lhs, const i128 rhs) noexcept {
+ if (lhs == 0 && rhs == 0) {
+ return false;
+ }
+
+ const bool lhsIsNegative = std::signbit(lhs);
+ const bool rhsIsNegative = std::signbit(rhs);
+
+ if (lhsIsNegative && !rhsIsNegative) {
+ return true;
+ }
+
+ if (!lhsIsNegative && rhsIsNegative) {
+ return false;
+ }
+
+ // both are negative or both are positive
+ if (GetHigh(lhs) != GetHigh(rhs)) {
+ return GetHigh(lhs) < GetHigh(rhs);
+ }
+
+ return GetLow(lhs) < GetLow(rhs);
+}
+
+constexpr bool operator>(const ui128 lhs, const ui128 rhs) noexcept {
+ return rhs < lhs;
+}
+
+constexpr bool operator>(const i128 lhs, const i128 rhs) noexcept {
+ return rhs < lhs;
+}
+
+constexpr bool operator<=(const ui128 lhs, const ui128 rhs) noexcept {
+ return !(rhs < lhs);
+}
+
+constexpr bool operator<=(const i128 lhs, const i128 rhs) noexcept {
+ return !(rhs < lhs);
+}
+
+constexpr bool operator>=(const ui128 lhs, const ui128 rhs) noexcept {
+ return !(lhs < rhs);
+}
+
+constexpr bool operator>=(const i128 lhs, const i128 rhs) noexcept {
+ return !(lhs < rhs);
+}
+
+constexpr ui128 operator+(const ui128 lhs, const ui128 rhs) noexcept {
+ const ui128 result{GetHigh(lhs) + GetHigh(rhs), GetLow(lhs) + GetLow(rhs)};
+ if (GetLow(result) < GetLow(lhs)) {
+ return ui128{GetHigh(result) + 1, GetLow(result)};
+ }
+ return result;
+}
+
+constexpr i128 operator+(const i128 lhs, const i128 rhs) noexcept {
+ const i128 result{GetHigh(lhs) + GetHigh(rhs), GetLow(lhs) + GetLow(rhs)};
+ if (GetLow(result) < GetLow(lhs)) {
+ return i128{GetHigh(result) + 1, GetLow(result)};
+ }
+ return result;
+}
+
+constexpr ui128 operator-(const ui128 lhs, const ui128 rhs) noexcept {
+ const ui128 result{GetHigh(lhs) - GetHigh(rhs), GetLow(lhs) - GetLow(rhs)};
+ if (GetLow(result) > GetLow(lhs)) { // underflow
+ return ui128{GetHigh(result) - 1, GetLow(result)};
+ }
+ return result;
+}
+
+constexpr i128 operator-(const i128 lhs, const i128 rhs) noexcept {
+ const i128 result{GetHigh(lhs) - GetHigh(rhs), GetLow(lhs) - GetLow(rhs)};
+ if (GetLow(result) > GetLow(lhs)) { // underflow
+ return i128{GetHigh(result) - 1, GetLow(result)};
+ }
+ return result;
+}
+
+constexpr ui128 operator-(const ui128 num) noexcept {
+ const ui128 result{~GetHigh(num), ~GetLow(num) + 1};
+ if (GetLow(result) == 0) {
+ return ui128{GetHigh(result) + 1, GetLow(result)};
+ }
+ return result;
+}
+
+constexpr i128 operator-(const i128 num) noexcept {
+ const i128 result{~GetHigh(num), ~GetLow(num) + 1};
+ if (GetLow(result) == 0) {
+ return i128{GetHigh(result) + 1, GetLow(result)};
+ }
+ return result;
+}
+
+constexpr ui128 operator*(const ui128 lhs, const ui128 rhs) noexcept {
+ if (rhs == 0) {
+ return 0;
+ }
+ if (rhs == 1) {
+ return lhs;
+ }
+
+ ui128 result{};
+ ui128 t = rhs;
+
+ for (size_t i = 0; i < 128; ++i) {
+ if ((t & 1) != 0) {
+ result += (lhs << i);
+ }
+
+ t = t >> 1;
+ }
+
+ return result;
+}
+
+constexpr i128 operator*(const i128 lhs, const i128 rhs) noexcept {
+ if (rhs == 0) {
+ return 0;
+ }
+ if (rhs == 1) {
+ return lhs;
+ }
+
+ i128 result{};
+ i128 t = rhs;
+
+ for (size_t i = 0; i < 128; ++i) {
+ if ((t & 1) != 0) {
+ result += (lhs << i);
+ }
+
+ t = t >> 1;
+ }
+
+ return result;
+}
+
+namespace NPrivateInt128 {
+ // NOTE: division by zero is UB and can be changed in future
+ constexpr void DivMod128(const ui128 lhs, const ui128 rhs, ui128* const quo, ui128* const rem) {
+ if (!quo && !rem) {
+ return;
+ }
+
+ constexpr size_t n_udword_bits = sizeof(ui64) * CHAR_BIT;
+ constexpr size_t n_utword_bits = sizeof(ui128) * CHAR_BIT;
+
+ ui128 q{};
+ ui128 r{};
+
+ unsigned sr{};
+
+ /* special cases, X is unknown, K != 0 */
+ if (GetHigh(lhs) == 0)
+ {
+ if (GetHigh(rhs) == 0)
+ {
+ /* 0 X
+ * ---
+ * 0 X
+ */
+ if (rem) {
+ *rem = GetLow(lhs) % GetLow(rhs);
+ }
+ if (quo) {
+ *quo = GetLow(lhs) / GetLow(rhs);
+ }
+ return;
+ }
+ /* 0 X
+ * ---
+ * K X
+ */
+ if (rem) {
+ *rem = GetLow(lhs);
+ }
+ if (quo) {
+ *quo = 0;
+ }
+ return;
+ }
+ /* n.s.high != 0 */
+ if (GetLow(rhs) == 0)
+ {
+ if (GetHigh(rhs) == 0)
+ {
+ /* K X
+ * ---
+ * 0 0
+ */
+ if (rem) {
+ *rem = GetHigh(lhs) % GetLow(rhs);
+ }
+ if (quo) {
+ *quo = GetHigh(lhs) / GetLow(rhs);
+ }
+ return;
+ }
+ /* d.s.high != 0 */
+ if (GetLow(lhs) == 0)
+ {
+ /* K 0
+ * ---
+ * K 0
+ */
+ if (rem) {
+ *rem = ui128{GetHigh(lhs) % GetHigh(rhs), 0};
+ }
+ if (quo) {
+ *quo = GetHigh(lhs) / GetHigh(rhs);
+ }
+ return;
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ if ((GetHigh(rhs) & (GetHigh(rhs) - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem) {
+ *rem = ui128{GetHigh(lhs) & (GetHigh(rhs) - 1), GetLow(lhs)};
+ }
+ if (quo) {
+ *quo = GetHigh(lhs) >> CountLeadingZeroBits(GetHigh(rhs));
+ }
+ return;
+ }
+ /* K K
+ * ---
+ * K 0
+ */
+ sr = CountLeadingZeroBits(GetHigh(rhs)) - CountLeadingZeroBits(GetHigh(lhs));
+ /* 0 <= sr <= n_udword_bits - 2 or sr large */
+ if (sr > n_udword_bits - 2)
+ {
+ if (rem) {
+ *rem = lhs;
+ }
+ if (quo) {
+ *quo = 0;
+ }
+ return;
+ }
+ ++sr;
+ /* 1 <= sr <= n_udword_bits - 1 */
+ /* q.all = n.all << (n_utword_bits - sr); */
+ q = ui128{
+ GetLow(lhs) << (n_udword_bits - sr),
+ 0
+ };
+ r = ui128{
+ GetHigh(lhs) >> sr,
+ (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
+ };
+ }
+ else /* d.s.low != 0 */
+ {
+ if (GetHigh(rhs) == 0)
+ {
+ /* K X
+ * ---
+ * 0 K
+ */
+ if ((GetLow(rhs) & (GetLow(rhs) - 1)) == 0) /* if d is a power of 2 */
+ {
+ if (rem) {
+ *rem = ui128{0, GetLow(lhs) & (GetLow(rhs) - 1)};
+ }
+ if (GetLow(rhs) == 1) {
+ if (quo) {
+ *quo = lhs;
+ }
+ return;
+ }
+ sr = CountTrailingZeroBits(GetLow(rhs));
+ if (quo) {
+ *quo = ui128{
+ GetHigh(lhs) >> sr,
+ (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
+ };
+ return;
+ }
+ }
+ /* K X
+ * ---
+ * 0 K
+ */
+ sr = 1 + n_udword_bits + CountLeadingZeroBits(GetLow(rhs))
+ - CountLeadingZeroBits(GetHigh(lhs));
+ /* 2 <= sr <= n_utword_bits - 1
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ */
+ if (sr == n_udword_bits)
+ {
+ q = ui128{GetLow(lhs), 0};
+ r = ui128{0, GetHigh(lhs)};
+ }
+ else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
+ {
+ q = ui128{
+ GetLow(lhs) << (n_udword_bits - sr),
+ 0
+ };
+ r = ui128{
+ GetHigh(lhs) >> sr,
+ (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
+ };
+ }
+ else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
+ {
+ q = ui128{
+ (GetHigh(lhs) << (n_utword_bits - sr)) | (GetLow(lhs) >> (sr - n_udword_bits)),
+ GetLow(lhs) << (n_utword_bits - sr)
+ };
+ r = ui128{
+ 0,
+ GetHigh(lhs) >> (sr - n_udword_bits)
+ };
+ }
+ }
+ else
+ {
+ /* K X
+ * ---
+ * K K
+ */
+ sr = CountLeadingZeroBits(GetHigh(rhs)) - CountLeadingZeroBits(GetHigh(lhs));
+ /*0 <= sr <= n_udword_bits - 1 or sr large */
+ if (sr > n_udword_bits - 1)
+ {
+ if (rem) {
+ *rem = lhs;
+ }
+ if (quo) {
+ *quo = 0;
+ }
+ return;
+ }
+ ++sr;
+ /* 1 <= sr <= n_udword_bits
+ * q.all = n.all << (n_utword_bits - sr);
+ * r.all = n.all >> sr;
+ */
+ if (sr == n_udword_bits)
+ {
+ q = ui128{
+ GetLow(lhs),
+ 0
+ };
+ r = ui128{
+ 0,
+ GetHigh(lhs)
+ };
+ }
+ else
+ {
+ r = ui128{
+ GetHigh(lhs) >> sr,
+ (GetHigh(lhs) << (n_udword_bits - sr)) | (GetLow(lhs) >> sr)
+ };
+ q = ui128{
+ GetLow(lhs) << (n_udword_bits - sr),
+ 0
+ };
+ }
+ }
+ }
+ /* Not a special case
+ * q and r are initialized with:
+ * q = n << (128 - sr);
+ * r = n >> sr;
+ * 1 <= sr <= 128 - 1
+ */
+ ui32 carry = 0;
+ for (; sr > 0; --sr)
+ {
+ /* r:q = ((r:q) << 1) | carry */
+ r = ui128{
+ (GetHigh(r) << 1) | (GetLow(r) >> (n_udword_bits - 1)),
+ (GetLow(r) << 1) | (GetHigh(q) >> (n_udword_bits - 1))
+ };
+ q = ui128{
+ (GetHigh(q) << 1) | (GetLow(q) >> (n_udword_bits - 1)),
+ (GetLow(q) << 1) | carry
+ };
+ carry = 0;
+ if (r >= rhs) {
+ r -= rhs;
+ carry = 1;
+ }
+ }
+ q = (q << 1) | carry;
+ if (rem) {
+ *rem = r;
+ }
+ if (quo) {
+ *quo = q;
+ }
+ }
+
+ struct TSignedDivisionResult {
+ i128 Quotient;
+ i128 Remainder;
+ };
+
+ constexpr TSignedDivisionResult Divide(i128 lhs, i128 rhs) noexcept;
+}
+
+constexpr ui128 operator/(const ui128 lhs, const ui128 rhs) noexcept {
+ ui128 quotient{};
+ NPrivateInt128::DivMod128(lhs, rhs, &quotient, nullptr);
+ return quotient;
+}
+
+constexpr i128 operator/(const i128 lhs, const i128 rhs) noexcept {
+ i128 a = std::abs(lhs);
+ i128 b = std::abs(rhs);
+
+ ui128 quotient{};
+ NPrivateInt128::DivMod128(a, b, &quotient, nullptr);
+ if (std::signbit(lhs) ^ std::signbit(rhs)) {
+ quotient = -quotient;
+ }
+ return quotient;
+}
+
+constexpr ui128 operator%(const ui128 lhs, const ui128 rhs) noexcept {
+ ui128 remainder{};
+ NPrivateInt128::DivMod128(lhs, rhs, nullptr, &remainder);
+ return remainder;
+}
+
+constexpr i128 operator%(const i128 lhs, const i128 rhs) noexcept {
+ i128 a = std::abs(lhs);
+ i128 b = std::abs(rhs);
+ ui128 remainder{};
+ NPrivateInt128::DivMod128(a, b, nullptr, &remainder);
+ if (std::signbit(lhs)) {
+ remainder = -remainder;
+ }
+ return remainder;
+}
+
+constexpr ui128 operator<<(const ui128 lhs, int n) noexcept {
+ if (n < 64) {
+ if (n != 0) {
+ return
+ ui128{
+ (GetHigh(lhs) << n) | (GetLow(lhs) >> (64 - n)),
+ GetLow(lhs) << n
+ };
+ }
+ return lhs;
+ }
+ return ui128{GetLow(lhs) << (n - 64), 0};
+}
+
+constexpr ui128 operator>>(const ui128 lhs, int n) noexcept {
+ if (n < 64) {
+ if (n != 0) {
+ return
+ ui128{
+ GetHigh(lhs) >> n,
+ (GetLow(lhs) >> n) | (GetHigh(lhs) << (64 - n))
+ };
+ }
+ return lhs;
+ }
+ return ui128{0, GetHigh(lhs) >> (n - 64)};
+}
+
+
+constexpr bool operator!(const ui128 num) noexcept {
+ return !GetHigh(num) && !GetLow(num);
+}
+
+constexpr ui128 operator~(const ui128 num) noexcept {
+ return ui128{~GetHigh(num), ~GetLow(num)};
+}
+
+constexpr ui128 operator|(const ui128 lhs, const ui128 rhs) noexcept {
+ return ui128{GetHigh(lhs) | GetHigh(rhs), GetLow(lhs) | GetLow(rhs)};
+}
+
+constexpr ui128 operator&(const ui128 lhs, const ui128 rhs) noexcept {
+ return ui128{GetHigh(lhs) & GetHigh(rhs), GetLow(lhs) & GetLow(rhs)};
+}
+
+constexpr ui128 operator^(const ui128 lhs, const ui128 rhs) noexcept {
+ return ui128{GetHigh(lhs) ^ GetHigh(rhs), GetLow(lhs) ^ GetLow(rhs)};
+}
+
+
+IOutputStream& operator<<(IOutputStream& out, const ui128& other);
+
+// For THashMap
+template <>
+struct THash<ui128> {
+ inline size_t operator()(const ui128& num) const {
+ return THash<ui64>()(GetHigh(num)) + THash<ui64>()(GetLow(num));
+ }
+};
+
+template <>
+class TSerializer<ui128> {
+public:
+ static void Save(IOutputStream* out, const ui128& Number);
+ static void Load(IInputStream* in, ui128& Number);
+};
+
+template <>
+inline TString ToString<ui128>(const ui128& number) {
+ return TStringBuilder{} << number;
+}
+
+template <>
+inline ui128 FromStringImpl<ui128>(const char* data, size_t length) {
+ if (length < 20) {
+ return ui128{ FromString<ui64>(data, length) };
+ } else {
+ ui128 result = 0;
+ const TStringBuf string(data, length);
+ for (auto&& c : string) {
+ if (!std::isdigit(c)) {
ythrow TFromStringException() << "Unexpected symbol \""sv << c << "\""sv;
- }
-
- ui128 x1 = result;
- ui128 x2 = x1 + x1;
- ui128 x4 = x2 + x2;
- ui128 x8 = x4 + x4;
- ui128 x10 = x8 + x2;
- ui128 s = c - '0';
- result = x10 + s;
-
- if (GetHigh(result) < GetHigh(x1)) {
+ }
+
+ ui128 x1 = result;
+ ui128 x2 = x1 + x1;
+ ui128 x4 = x2 + x2;
+ ui128 x8 = x4 + x4;
+ ui128 x10 = x8 + x2;
+ ui128 s = c - '0';
+ result = x10 + s;
+
+ if (GetHigh(result) < GetHigh(x1)) {
ythrow TFromStringException() << TStringBuf("Integer overflow");
- }
- }
-
- return result;
- }
-}
-
-#if defined(Y_HAVE_INT128)
-template <>
-inline TString ToString<unsigned __int128>(const unsigned __int128& number) {
- return ToString(ui128{number});
-}
-
-template <>
-inline unsigned __int128 FromStringImpl<unsigned __int128>(const char* data, size_t length) {
- return static_cast<unsigned __int128>(FromString<ui128>(data, length));
-}
-#endif
-
-// operators
-
-
-namespace NPrivateInt128 {
- // very naive algorithm of division
- // no contract for divide by zero (i.e. it is UB) (may be changed in future)
- constexpr TSignedDivisionResult Divide(i128 lhs, i128 rhs) noexcept {
- TSignedDivisionResult result {};
-
- // check trivial cases
- // X/0 = +/- inf, X%0 = X
- if (rhs == 0) {
- // UB, let's return: `X / 0 = +inf`, and `X % 0 = X`
- result.Quotient = std::signbit(lhs) ? std::numeric_limits<i128>::min() : std::numeric_limits<i128>::max();
- result.Remainder = lhs;
- }
-
- // 0/Y = 0, 0%Y = 0
- else if (lhs == 0) {
- result.Quotient = 0;
- result.Remainder = 0;
- }
-
- // X/1 = X, X%1 = 0
- else if (rhs == 1) {
- result.Quotient = lhs;
- result.Remainder = 0;
- }
-
- // X/-1 = -X, X%(-1) = 0
- else if (rhs == -1) {
- result.Quotient = -lhs;
- result.Remainder = 0;
- }
-
- // abs(X)<abs(Y), X/Y = 0, X%Y = X
- else if (std::abs(lhs) < std::abs(rhs)) {
- result.Quotient = 0;
- result.Remainder = lhs;
- }
-
- else if (lhs == rhs) {
- result.Quotient = 1;
- result.Remainder = 0;
- }
-
- else if (lhs == -rhs) {
- result.Quotient = -1;
- result.Remainder = 0;
- }
-
- else if (std::abs(lhs) > std::abs(rhs)) {
- const bool quotientMustBeNegative = std::signbit(lhs) ^ std::signbit(rhs);
- const bool remainderMustBeNegative = std::signbit(lhs);
-
- lhs = std::abs(lhs);
- rhs = std::abs(rhs);
-
- // result is division of two ui64
- if (GetHigh(lhs) == 0 && GetHigh(rhs) == 0) {
- result.Quotient = GetLow(lhs) / GetLow(rhs);
- result.Remainder = GetLow(lhs) % GetLow(rhs);
- }
-
- // naive shift-and-subtract
- // https://stackoverflow.com/questions/5386377/division-without-using
- i128 denominator = rhs;
- result.Quotient = 0;
- result.Remainder = lhs;
-
- const size_t shift = MostSignificantBit(lhs) - MostSignificantBit(denominator);
- denominator <<= shift;
-
- for (size_t i = 0; i <= shift; ++i) {
- result.Quotient <<= 1;
- if (result.Remainder >= denominator) {
- result.Remainder -= denominator;
- result.Quotient |= 1;
- }
- denominator >>= 1;
- }
-
- if (quotientMustBeNegative) {
- result.Quotient = -result.Quotient;
- }
-
- if (remainderMustBeNegative) {
- result.Remainder = -result.Remainder;
- }
- }
-
- return result;
- }
-} // namespace NPrivateInt128
-
-constexpr i128 operator<<(const i128 lhs, int n) noexcept {
- if (n < 64) {
- if (n != 0) {
- return
- i128{
- (GetHigh(lhs) << n) | (GetLow(lhs) >> (64 - n)),
- GetLow(lhs) << n
- };
- }
- return lhs;
- }
- return i128{GetLow(lhs) << (n - 64), 0};
-}
-
-constexpr i128 operator>>(const i128 lhs, int n) noexcept {
- if (n < 64) {
- if (n != 0) {
- return
- i128{
- GetHigh(lhs) >> n,
- (GetLow(lhs) >> n) | (GetHigh(lhs) << (64 - n))
- };
- }
- return lhs;
- }
- return i128{0, GetHigh(lhs) >> (n - 64)};
-}
-
-constexpr bool operator!(const i128 num) noexcept {
- return !GetHigh(num) && !GetLow(num);
-}
-
-constexpr i128 operator~(const i128 num) noexcept {
- return i128{~GetHigh(num), ~GetLow(num)};
-}
-
-constexpr i128 operator|(const i128 lhs, const i128 rhs) noexcept {
- return i128{GetHigh(lhs) | GetHigh(rhs), GetLow(lhs) | GetLow(rhs)};
-}
-
-constexpr i128 operator&(const i128 lhs, const i128 rhs) noexcept {
- return i128{GetHigh(lhs) & GetHigh(rhs), GetLow(lhs) & GetLow(rhs)};
-}
-
-constexpr i128 operator^(const i128 lhs, const i128 rhs) noexcept {
- return i128{GetHigh(lhs) ^ GetHigh(rhs), GetLow(lhs) ^ GetLow(rhs)};
-}
-
-
-IOutputStream& operator<<(IOutputStream& out, const i128& other);
-
-// For THashMap
-template <>
-struct THash<i128> {
- inline size_t operator()(const i128& num) const {
- return THash<ui64>()(GetHigh(num)) + THash<ui64>()(GetLow(num));
- }
-};
-
-template <>
-class TSerializer<i128> {
-public:
- static void Save(IOutputStream* out, const i128& Number);
- static void Load(IInputStream* in, i128& Number);
-};
-
-template <>
-inline TString ToString<i128>(const i128& number) {
- return TStringBuilder{} << number;
-}
-
-template <>
-inline i128 FromStringImpl<i128>(const char* data, size_t length) {
- if (length < 20) {
- return i128{ FromString<ui64>(data, length) };
- } else {
- i128 result = 0;
- const TStringBuf string(data, length);
- for (auto&& c : string) {
- if (!std::isdigit(c)) {
+ }
+ }
+
+ return result;
+ }
+}
+
+#if defined(Y_HAVE_INT128)
+template <>
+inline TString ToString<unsigned __int128>(const unsigned __int128& number) {
+ return ToString(ui128{number});
+}
+
+template <>
+inline unsigned __int128 FromStringImpl<unsigned __int128>(const char* data, size_t length) {
+ return static_cast<unsigned __int128>(FromString<ui128>(data, length));
+}
+#endif
+
+// operators
+
+
+namespace NPrivateInt128 {
+ // very naive algorithm of division
+ // no contract for divide by zero (i.e. it is UB) (may be changed in future)
+ constexpr TSignedDivisionResult Divide(i128 lhs, i128 rhs) noexcept {
+ TSignedDivisionResult result {};
+
+ // check trivial cases
+ // X/0 = +/- inf, X%0 = X
+ if (rhs == 0) {
+ // UB, let's return: `X / 0 = +inf`, and `X % 0 = X`
+ result.Quotient = std::signbit(lhs) ? std::numeric_limits<i128>::min() : std::numeric_limits<i128>::max();
+ result.Remainder = lhs;
+ }
+
+ // 0/Y = 0, 0%Y = 0
+ else if (lhs == 0) {
+ result.Quotient = 0;
+ result.Remainder = 0;
+ }
+
+ // X/1 = X, X%1 = 0
+ else if (rhs == 1) {
+ result.Quotient = lhs;
+ result.Remainder = 0;
+ }
+
+ // X/-1 = -X, X%(-1) = 0
+ else if (rhs == -1) {
+ result.Quotient = -lhs;
+ result.Remainder = 0;
+ }
+
+ // abs(X)<abs(Y), X/Y = 0, X%Y = X
+ else if (std::abs(lhs) < std::abs(rhs)) {
+ result.Quotient = 0;
+ result.Remainder = lhs;
+ }
+
+ else if (lhs == rhs) {
+ result.Quotient = 1;
+ result.Remainder = 0;
+ }
+
+ else if (lhs == -rhs) {
+ result.Quotient = -1;
+ result.Remainder = 0;
+ }
+
+ else if (std::abs(lhs) > std::abs(rhs)) {
+ const bool quotientMustBeNegative = std::signbit(lhs) ^ std::signbit(rhs);
+ const bool remainderMustBeNegative = std::signbit(lhs);
+
+ lhs = std::abs(lhs);
+ rhs = std::abs(rhs);
+
+ // result is division of two ui64
+ if (GetHigh(lhs) == 0 && GetHigh(rhs) == 0) {
+ result.Quotient = GetLow(lhs) / GetLow(rhs);
+ result.Remainder = GetLow(lhs) % GetLow(rhs);
+ }
+
+ // naive shift-and-subtract
+ // https://stackoverflow.com/questions/5386377/division-without-using
+ i128 denominator = rhs;
+ result.Quotient = 0;
+ result.Remainder = lhs;
+
+ const size_t shift = MostSignificantBit(lhs) - MostSignificantBit(denominator);
+ denominator <<= shift;
+
+ for (size_t i = 0; i <= shift; ++i) {
+ result.Quotient <<= 1;
+ if (result.Remainder >= denominator) {
+ result.Remainder -= denominator;
+ result.Quotient |= 1;
+ }
+ denominator >>= 1;
+ }
+
+ if (quotientMustBeNegative) {
+ result.Quotient = -result.Quotient;
+ }
+
+ if (remainderMustBeNegative) {
+ result.Remainder = -result.Remainder;
+ }
+ }
+
+ return result;
+ }
+} // namespace NPrivateInt128
+
+constexpr i128 operator<<(const i128 lhs, int n) noexcept {
+ if (n < 64) {
+ if (n != 0) {
+ return
+ i128{
+ (GetHigh(lhs) << n) | (GetLow(lhs) >> (64 - n)),
+ GetLow(lhs) << n
+ };
+ }
+ return lhs;
+ }
+ return i128{GetLow(lhs) << (n - 64), 0};
+}
+
+constexpr i128 operator>>(const i128 lhs, int n) noexcept {
+ if (n < 64) {
+ if (n != 0) {
+ return
+ i128{
+ GetHigh(lhs) >> n,
+ (GetLow(lhs) >> n) | (GetHigh(lhs) << (64 - n))
+ };
+ }
+ return lhs;
+ }
+ return i128{0, GetHigh(lhs) >> (n - 64)};
+}
+
+constexpr bool operator!(const i128 num) noexcept {
+ return !GetHigh(num) && !GetLow(num);
+}
+
+constexpr i128 operator~(const i128 num) noexcept {
+ return i128{~GetHigh(num), ~GetLow(num)};
+}
+
+constexpr i128 operator|(const i128 lhs, const i128 rhs) noexcept {
+ return i128{GetHigh(lhs) | GetHigh(rhs), GetLow(lhs) | GetLow(rhs)};
+}
+
+constexpr i128 operator&(const i128 lhs, const i128 rhs) noexcept {
+ return i128{GetHigh(lhs) & GetHigh(rhs), GetLow(lhs) & GetLow(rhs)};
+}
+
+constexpr i128 operator^(const i128 lhs, const i128 rhs) noexcept {
+ return i128{GetHigh(lhs) ^ GetHigh(rhs), GetLow(lhs) ^ GetLow(rhs)};
+}
+
+
+IOutputStream& operator<<(IOutputStream& out, const i128& other);
+
+// For THashMap
+template <>
+struct THash<i128> {
+ inline size_t operator()(const i128& num) const {
+ return THash<ui64>()(GetHigh(num)) + THash<ui64>()(GetLow(num));
+ }
+};
+
+template <>
+class TSerializer<i128> {
+public:
+ static void Save(IOutputStream* out, const i128& Number);
+ static void Load(IInputStream* in, i128& Number);
+};
+
+template <>
+inline TString ToString<i128>(const i128& number) {
+ return TStringBuilder{} << number;
+}
+
+template <>
+inline i128 FromStringImpl<i128>(const char* data, size_t length) {
+ if (length < 20) {
+ return i128{ FromString<ui64>(data, length) };
+ } else {
+ i128 result = 0;
+ const TStringBuf string(data, length);
+ for (auto&& c : string) {
+ if (!std::isdigit(c)) {
ythrow TFromStringException() << "Unexpected symbol \""sv << c << "\""sv;
- }
-
- i128 x1 = result;
- i128 x2 = x1 + x1;
- i128 x4 = x2 + x2;
- i128 x8 = x4 + x4;
- i128 x10 = x8 + x2;
- i128 s = c - '0';
- result = x10 + s;
-
- if (GetHigh(result) < GetHigh(x1)) {
+ }
+
+ i128 x1 = result;
+ i128 x2 = x1 + x1;
+ i128 x4 = x2 + x2;
+ i128 x8 = x4 + x4;
+ i128 x10 = x8 + x2;
+ i128 s = c - '0';
+ result = x10 + s;
+
+ if (GetHigh(result) < GetHigh(x1)) {
ythrow TFromStringException() << TStringBuf("Integer overflow");
- }
- }
-
- return result;
- }
-}
-
-#if defined(Y_HAVE_INT128)
-template <>
-inline TString ToString<signed __int128>(const signed __int128& number) {
- return ToString(i128{number});
-}
-
-template <>
-inline signed __int128 FromStringImpl<signed __int128>(const char* data, size_t length) {
- return static_cast<signed __int128>(FromString<i128>(data, length));
-}
-#endif
-
-template <bool IsSigned>
-Y_FORCE_INLINE size_t MostSignificantBit(const TInteger128<IsSigned> v) {
- if (ui64 hi = GetHigh(v)) {
- return MostSignificantBit(hi) + 64;
- }
- return MostSignificantBit(GetLow(v));
-}
+ }
+ }
+
+ return result;
+ }
+}
+
+#if defined(Y_HAVE_INT128)
+template <>
+inline TString ToString<signed __int128>(const signed __int128& number) {
+ return ToString(i128{number});
+}
+
+template <>
+inline signed __int128 FromStringImpl<signed __int128>(const char* data, size_t length) {
+ return static_cast<signed __int128>(FromString<i128>(data, length));
+}
+#endif
+
+template <bool IsSigned>
+Y_FORCE_INLINE size_t MostSignificantBit(const TInteger128<IsSigned> v) {
+ if (ui64 hi = GetHigh(v)) {
+ return MostSignificantBit(hi) + 64;
+ }
+ return MostSignificantBit(GetLow(v));
+}
diff --git a/library/cpp/int128/int128_common.h b/library/cpp/int128/int128_common.h
index 6f70f09bee..7ad6485b33 100644
--- a/library/cpp/int128/int128_common.h
+++ b/library/cpp/int128/int128_common.h
@@ -1 +1 @@
-#pragma once
+#pragma once
diff --git a/library/cpp/int128/int128_util.h b/library/cpp/int128/int128_util.h
index 7a5ca2c250..b3208eaed3 100644
--- a/library/cpp/int128/int128_util.h
+++ b/library/cpp/int128/int128_util.h
@@ -1,15 +1,15 @@
-#pragma once
-
-#include <util/generic/bitops.h>
-#include <limits>
-
-namespace NPrivateInt128 {
- // will be moved to util/ later
- template <typename T>
- constexpr unsigned CountLeadingZeroBits(const T value) {
- if (value == 0) {
- return std::numeric_limits<std::make_unsigned_t<T>>::digits;
- }
- return std::numeric_limits<std::make_unsigned_t<T>>::digits - GetValueBitCount(value);
- }
-}
+#pragma once
+
+#include <util/generic/bitops.h>
+#include <limits>
+
+namespace NPrivateInt128 {
+ // will be moved to util/ later
+ template <typename T>
+ constexpr unsigned CountLeadingZeroBits(const T value) {
+ if (value == 0) {
+ return std::numeric_limits<std::make_unsigned_t<T>>::digits;
+ }
+ return std::numeric_limits<std::make_unsigned_t<T>>::digits - GetValueBitCount(value);
+ }
+}
diff --git a/library/cpp/int128/ut/.gitignore b/library/cpp/int128/ut/.gitignore
index 36abcb2a2c..46c7056544 100644
--- a/library/cpp/int128/ut/.gitignore
+++ b/library/cpp/int128/ut/.gitignore
@@ -1,2 +1,2 @@
-library-int128-ut
-
+library-int128-ut
+
diff --git a/library/cpp/int128/ut/i128_and_intrinsic_identity_ut.cpp b/library/cpp/int128/ut/i128_and_intrinsic_identity_ut.cpp
index dbb7507a73..c7de9b36c7 100644
--- a/library/cpp/int128/ut/i128_and_intrinsic_identity_ut.cpp
+++ b/library/cpp/int128/ut/i128_and_intrinsic_identity_ut.cpp
@@ -1,598 +1,598 @@
-#include "int128_ut_helpers.h"
-
+#include "int128_ut_helpers.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-#include <array>
-#include <type_traits>
-
-#if defined(Y_HAVE_INT128)
-bool IsIdentical(const i128 a, const signed __int128 b) {
- const std::array<ui8, 16> arrayA = NInt128Private::GetAsArray(a);
- const std::array<ui8, 16> arrayB = NInt128Private::GetAsArray(b);
- return arrayA == arrayB;
-}
-
-Y_UNIT_TEST_SUITE(i128_And_i8_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_i8_Zero) {
- i8 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_Minus1) {
- i8 n = -1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_Plus1) {
- i8 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_Minus42) {
- i8 n = -42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_Plus42) {
- i8 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_Min) {
- i8 n = std::numeric_limits<i8>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_Max) {
- i8 n = std::numeric_limits<i8>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_MinPlus1) {
- i8 n = std::numeric_limits<i8>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i8_MaxMinus1) {
- i8 n = std::numeric_limits<i8>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_i16_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_i16_Zero) {
- i16 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_Minus1) {
- i16 n = -1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_Plus1) {
- i16 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_Minus42) {
- i16 n = -42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_Plus42) {
- i16 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_Min) {
- i16 n = std::numeric_limits<i16>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_Max) {
- i16 n = std::numeric_limits<i16>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_MinPlus1) {
- i16 n = std::numeric_limits<i16>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i16_MaxMinus1) {
- i16 n = std::numeric_limits<i16>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_i32_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_i32_Zero) {
- i32 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_Minus1) {
- i32 n = -1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_Plus1) {
- i32 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_Minus42) {
- i32 n = -42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_Plus42) {
- i32 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_Min) {
- i32 n = std::numeric_limits<i32>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_Max) {
- i32 n = std::numeric_limits<i32>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_MinPlus1) {
- i32 n = std::numeric_limits<i32>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i32_MaxMinus1) {
- i32 n = std::numeric_limits<i32>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_i64_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_i64_Zero) {
- i64 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_Minus1) {
- i64 n = -1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_Plus1) {
- i64 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_Minus42) {
- i64 n = -42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_Plus42) {
- i64 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_Min) {
- i64 n = std::numeric_limits<i64>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_Max) {
- i64 n = std::numeric_limits<i64>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_MinPlus1) {
- i64 n = std::numeric_limits<i64>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_i64_MaxMinus1) {
- i64 n = std::numeric_limits<i64>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_signed_int128_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_signed_int128_Zero) {
- signed __int128 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_Minus1) {
- signed __int128 n = -1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_Plus1) {
- signed __int128 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_Minus42) {
- signed __int128 n = -42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_Plus42) {
- signed __int128 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_Min) {
- signed __int128 n = std::numeric_limits<signed __int128>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_Max) {
- signed __int128 n = std::numeric_limits<signed __int128>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_MinPlus1) {
- signed __int128 n = std::numeric_limits<signed __int128>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_signed_int128_MaxMinus1) {
- signed __int128 n = std::numeric_limits<signed __int128>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_ui8_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_ui8_Zero) {
- ui8 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui8_Plus1) {
- ui8 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui8_Plus42) {
- ui8 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui8_Min) {
- ui8 n = std::numeric_limits<i8>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui8_Max) {
- ui8 n = std::numeric_limits<i8>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui8_MinPlus1) {
- ui8 n = std::numeric_limits<i8>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui8_MaxMinus1) {
- ui8 n = std::numeric_limits<i8>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_ui16_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_ui16_Zero) {
- ui16 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui16_Plus1) {
- ui16 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui16_Plus42) {
- ui16 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui16_Min) {
- ui16 n = std::numeric_limits<i8>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui16_Max) {
- ui16 n = std::numeric_limits<i8>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui16_MinPlus1) {
- ui16 n = std::numeric_limits<i8>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui16_MaxMinus1) {
- ui16 n = std::numeric_limits<i8>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_ui32_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_ui32_Zero) {
- ui32 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui32_Plus1) {
- ui32 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui32_Plus42) {
- ui32 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui32_Min) {
- ui32 n = std::numeric_limits<i8>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui32_Max) {
- ui32 n = std::numeric_limits<i8>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui32_MinPlus1) {
- ui32 n = std::numeric_limits<i8>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui32_MaxMinus1) {
- ui32 n = std::numeric_limits<i8>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_ui64_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_ui64_Zero) {
- ui64 n = 0;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui64_Plus1) {
- ui64 n = 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui64_Plus42) {
- ui64 n = 42;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui64_Min) {
- ui64 n = std::numeric_limits<i8>::min();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui64_Max) {
- ui64 n = std::numeric_limits<i8>::max();
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui64_MinPlus1) {
- ui64 n = std::numeric_limits<i8>::min() + 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_ui64_MaxMinus1) {
- ui64 n = std::numeric_limits<i8>::max() - 1;
- i128 t1{n};
- signed __int128 t2{n};
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-
-Y_UNIT_TEST_SUITE(i128_And_unsigned_int128_BitwiseIdentity) {
- Y_UNIT_TEST(i128_from_unsigned_int128_Zero) {
- unsigned __int128 n = 0;
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_unsigned_int128_Plus1) {
- unsigned __int128 n = 1;
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_unsigned_int128_Plus42) {
- unsigned __int128 n = 42;
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_unsigned_int128_Min) {
- unsigned __int128 n = std::numeric_limits<i8>::min();
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_unsigned_int128_Max) {
- unsigned __int128 n = std::numeric_limits<i8>::max();
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_unsigned_int128_MinPlus1) {
- unsigned __int128 n = std::numeric_limits<i8>::min() + 1;
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-
- Y_UNIT_TEST(i128_from_unsigned_int128_MaxMinus1) {
- unsigned __int128 n = std::numeric_limits<i8>::max() - 1;
- i128 t1{n};
- signed __int128 t2 = static_cast<signed __int128>(n);
- UNIT_ASSERT(IsIdentical(t1, t2));
- }
-}
-#endif
+
+#include <util/generic/cast.h>
+
+#include <array>
+#include <type_traits>
+
+#if defined(Y_HAVE_INT128)
+bool IsIdentical(const i128 a, const signed __int128 b) {
+ const std::array<ui8, 16> arrayA = NInt128Private::GetAsArray(a);
+ const std::array<ui8, 16> arrayB = NInt128Private::GetAsArray(b);
+ return arrayA == arrayB;
+}
+
+Y_UNIT_TEST_SUITE(i128_And_i8_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_i8_Zero) {
+ i8 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_Minus1) {
+ i8 n = -1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_Plus1) {
+ i8 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_Minus42) {
+ i8 n = -42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_Plus42) {
+ i8 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_Min) {
+ i8 n = std::numeric_limits<i8>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_Max) {
+ i8 n = std::numeric_limits<i8>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_MinPlus1) {
+ i8 n = std::numeric_limits<i8>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i8_MaxMinus1) {
+ i8 n = std::numeric_limits<i8>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_i16_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_i16_Zero) {
+ i16 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_Minus1) {
+ i16 n = -1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_Plus1) {
+ i16 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_Minus42) {
+ i16 n = -42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_Plus42) {
+ i16 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_Min) {
+ i16 n = std::numeric_limits<i16>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_Max) {
+ i16 n = std::numeric_limits<i16>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_MinPlus1) {
+ i16 n = std::numeric_limits<i16>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i16_MaxMinus1) {
+ i16 n = std::numeric_limits<i16>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_i32_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_i32_Zero) {
+ i32 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_Minus1) {
+ i32 n = -1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_Plus1) {
+ i32 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_Minus42) {
+ i32 n = -42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_Plus42) {
+ i32 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_Min) {
+ i32 n = std::numeric_limits<i32>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_Max) {
+ i32 n = std::numeric_limits<i32>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_MinPlus1) {
+ i32 n = std::numeric_limits<i32>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i32_MaxMinus1) {
+ i32 n = std::numeric_limits<i32>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_i64_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_i64_Zero) {
+ i64 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_Minus1) {
+ i64 n = -1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_Plus1) {
+ i64 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_Minus42) {
+ i64 n = -42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_Plus42) {
+ i64 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_Min) {
+ i64 n = std::numeric_limits<i64>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_Max) {
+ i64 n = std::numeric_limits<i64>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_MinPlus1) {
+ i64 n = std::numeric_limits<i64>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_i64_MaxMinus1) {
+ i64 n = std::numeric_limits<i64>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_signed_int128_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_signed_int128_Zero) {
+ signed __int128 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_Minus1) {
+ signed __int128 n = -1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_Plus1) {
+ signed __int128 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_Minus42) {
+ signed __int128 n = -42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_Plus42) {
+ signed __int128 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_Min) {
+ signed __int128 n = std::numeric_limits<signed __int128>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_Max) {
+ signed __int128 n = std::numeric_limits<signed __int128>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_MinPlus1) {
+ signed __int128 n = std::numeric_limits<signed __int128>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_signed_int128_MaxMinus1) {
+ signed __int128 n = std::numeric_limits<signed __int128>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_ui8_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_ui8_Zero) {
+ ui8 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui8_Plus1) {
+ ui8 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui8_Plus42) {
+ ui8 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui8_Min) {
+ ui8 n = std::numeric_limits<i8>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui8_Max) {
+ ui8 n = std::numeric_limits<i8>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui8_MinPlus1) {
+ ui8 n = std::numeric_limits<i8>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui8_MaxMinus1) {
+ ui8 n = std::numeric_limits<i8>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_ui16_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_ui16_Zero) {
+ ui16 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui16_Plus1) {
+ ui16 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui16_Plus42) {
+ ui16 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui16_Min) {
+ ui16 n = std::numeric_limits<i8>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui16_Max) {
+ ui16 n = std::numeric_limits<i8>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui16_MinPlus1) {
+ ui16 n = std::numeric_limits<i8>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui16_MaxMinus1) {
+ ui16 n = std::numeric_limits<i8>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_ui32_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_ui32_Zero) {
+ ui32 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui32_Plus1) {
+ ui32 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui32_Plus42) {
+ ui32 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui32_Min) {
+ ui32 n = std::numeric_limits<i8>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui32_Max) {
+ ui32 n = std::numeric_limits<i8>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui32_MinPlus1) {
+ ui32 n = std::numeric_limits<i8>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui32_MaxMinus1) {
+ ui32 n = std::numeric_limits<i8>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_ui64_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_ui64_Zero) {
+ ui64 n = 0;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui64_Plus1) {
+ ui64 n = 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui64_Plus42) {
+ ui64 n = 42;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui64_Min) {
+ ui64 n = std::numeric_limits<i8>::min();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui64_Max) {
+ ui64 n = std::numeric_limits<i8>::max();
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui64_MinPlus1) {
+ ui64 n = std::numeric_limits<i8>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_ui64_MaxMinus1) {
+ ui64 n = std::numeric_limits<i8>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2{n};
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128_And_unsigned_int128_BitwiseIdentity) {
+ Y_UNIT_TEST(i128_from_unsigned_int128_Zero) {
+ unsigned __int128 n = 0;
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_unsigned_int128_Plus1) {
+ unsigned __int128 n = 1;
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_unsigned_int128_Plus42) {
+ unsigned __int128 n = 42;
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_unsigned_int128_Min) {
+ unsigned __int128 n = std::numeric_limits<i8>::min();
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_unsigned_int128_Max) {
+ unsigned __int128 n = std::numeric_limits<i8>::max();
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_unsigned_int128_MinPlus1) {
+ unsigned __int128 n = std::numeric_limits<i8>::min() + 1;
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+
+ Y_UNIT_TEST(i128_from_unsigned_int128_MaxMinus1) {
+ unsigned __int128 n = std::numeric_limits<i8>::max() - 1;
+ i128 t1{n};
+ signed __int128 t2 = static_cast<signed __int128>(n);
+ UNIT_ASSERT(IsIdentical(t1, t2));
+ }
+}
+#endif
diff --git a/library/cpp/int128/ut/i128_comparison_ut.cpp b/library/cpp/int128/ut/i128_comparison_ut.cpp
index 7b8d508815..8e38ac17e2 100644
--- a/library/cpp/int128/ut/i128_comparison_ut.cpp
+++ b/library/cpp/int128/ut/i128_comparison_ut.cpp
@@ -1,145 +1,145 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-Y_UNIT_TEST_SUITE(I128ComparisonPositiveWithPositiveSuite) {
- Y_UNIT_TEST(PositivePositiveGreater) {
- UNIT_ASSERT(i128{1} > i128{0});
- UNIT_ASSERT(i128{2} > i128{1});
- UNIT_ASSERT(i128{42} > i128{0});
- UNIT_ASSERT(i128{42} > i128{1});
- i128 big = i128{1, 0};
- UNIT_ASSERT(big > i128{1});
- UNIT_ASSERT(std::numeric_limits<i128>::max() > i128{0});
- }
-
- Y_UNIT_TEST(PositivePositiveGreaterOrEqual) {
- UNIT_ASSERT(i128{1} >= i128{0});
- UNIT_ASSERT(i128{2} >= i128{1});
- UNIT_ASSERT(i128{42} >= i128{0});
- UNIT_ASSERT(i128{42} >= i128{1});
- i128 big = i128{1, 0};
- UNIT_ASSERT(big >= i128{1});
- UNIT_ASSERT(std::numeric_limits<i128>::max() >= i128{0});
-
- UNIT_ASSERT(i128{0} >= i128{0});
- UNIT_ASSERT(i128{1} >= i128{1});
- UNIT_ASSERT(i128{2} >= i128{2});
- UNIT_ASSERT(i128{42} >= i128{42});
- UNIT_ASSERT(big >= big);
- UNIT_ASSERT(std::numeric_limits<i128>::max() >= std::numeric_limits<i128>::max());
- }
-
- Y_UNIT_TEST(PositivePositiveLess) {
- UNIT_ASSERT(i128{0} < i128{1});
- UNIT_ASSERT(i128{1} < i128{2});
- UNIT_ASSERT(i128{0} < i128{42});
- UNIT_ASSERT(i128{1} < i128{42});
- i128 big = i128{1, 0};
- UNIT_ASSERT(i128{1} < big);
- UNIT_ASSERT(i128{0} < std::numeric_limits<i128>::max());
- }
-
- Y_UNIT_TEST(PositivePositiveLessOrEqual) {
- UNIT_ASSERT(i128{0} <= i128{1});
- UNIT_ASSERT(i128{1} <= i128{2});
- UNIT_ASSERT(i128{0} <= i128{42});
- UNIT_ASSERT(i128{1} <= i128{42});
- i128 big = i128{1, 0};
- UNIT_ASSERT(i128{1} <= big);
- UNIT_ASSERT(i128{0} <= std::numeric_limits<i128>::max());
-
- UNIT_ASSERT(i128{0} <= i128{0});
- UNIT_ASSERT(i128{1} <= i128{1});
- UNIT_ASSERT(i128{2} <= i128{2});
- UNIT_ASSERT(i128{42} <= i128{42});
- UNIT_ASSERT(big <= big);
- UNIT_ASSERT(std::numeric_limits<i128>::max() <= std::numeric_limits<i128>::max());
- }
-}
-
-Y_UNIT_TEST_SUITE(I128ComparisonPositiveWithNegativeSuite) {
- Y_UNIT_TEST(PositiveNegativeGreater) {
- UNIT_ASSERT(i128{0} > i128{-1});
- UNIT_ASSERT(i128{2} > i128{-1});
- UNIT_ASSERT(i128{0} > i128{-42});
- UNIT_ASSERT(i128{42} > i128{-1});
- i128 big = i128{1, 0};
- UNIT_ASSERT(big > i128{-1});
- UNIT_ASSERT(std::numeric_limits<i128>::max() > i128{-1});
- }
-
- Y_UNIT_TEST(PositiveNegativeGreaterOrEqual) {
- UNIT_ASSERT(i128{0} >= i128{-1});
- UNIT_ASSERT(i128{2} >= i128{-1});
- UNIT_ASSERT(i128{0} >= i128{-42});
- UNIT_ASSERT(i128{42} >= i128{-1});
- i128 big = i128{1, 0};
- UNIT_ASSERT(big >= i128{-1});
- UNIT_ASSERT(std::numeric_limits<i128>::max() >= i128{-1});
- }
-
- Y_UNIT_TEST(NegativePositiveLess) {
- UNIT_ASSERT(i128{-1} < i128{0});
- UNIT_ASSERT(i128{-1} < i128{2});
- UNIT_ASSERT(i128{-42} < i128{0});
- UNIT_ASSERT(i128{-1} < i128{42});
- i128 big = i128{1, 0};
- UNIT_ASSERT(i128{-1} < big);
- UNIT_ASSERT(i128{-1} < std::numeric_limits<i128>::max());
- }
-
- Y_UNIT_TEST(NegativePositiveLessOrEqual) {
- UNIT_ASSERT(i128{-1} <= i128{0});
- UNIT_ASSERT(i128{-1} <= i128{2});
- UNIT_ASSERT(i128{-42} <= i128{0});
- UNIT_ASSERT(i128{-1} <= i128{42});
- i128 big = i128{1, 0};
- UNIT_ASSERT(i128{-1} <= big);
- UNIT_ASSERT(i128{-1} <= std::numeric_limits<i128>::max());
- }
-}
-
-Y_UNIT_TEST_SUITE(I128ComparisonNegativeWithNegativeSuite) {
- Y_UNIT_TEST(NegativeNegativeGreater) {
- UNIT_ASSERT(i128{-1} > i128{-2});
- UNIT_ASSERT(i128{-2} > i128{-3});
- UNIT_ASSERT(i128{-1} > i128{-42});
- UNIT_ASSERT(i128{-42} > i128{-142});
- i128 big = -i128{1, 0};
- UNIT_ASSERT(i128{-1} > big);
- UNIT_ASSERT(i128{-1} > std::numeric_limits<i128>::min());
- }
-
- Y_UNIT_TEST(NegativeNegativeGreaterOrEqual) {
- UNIT_ASSERT(i128{-1} >= i128{-2});
- UNIT_ASSERT(i128{-2} >= i128{-3});
- UNIT_ASSERT(i128{-1} >= i128{-42});
- UNIT_ASSERT(i128{-42} >= i128{-142});
- i128 big = -i128{1, 0};
- UNIT_ASSERT(i128{-1} >= big);
- UNIT_ASSERT(i128{-1} >= std::numeric_limits<i128>::min());
- }
-
- Y_UNIT_TEST(NegativeNegativeLess) {
- UNIT_ASSERT(i128{-2} < i128{-1});
- UNIT_ASSERT(i128{-3} < i128{-2});
- UNIT_ASSERT(i128{-42} < i128{-1});
- UNIT_ASSERT(i128{-142} < i128{42});
- i128 big = -i128{1, 0};
- UNIT_ASSERT(big < i128{-1});
- UNIT_ASSERT(std::numeric_limits<i128>::min() < i128{-1});
- }
-
- Y_UNIT_TEST(NegativeNegativeLessOrEqual) {
- UNIT_ASSERT(i128{-2} <= i128{-1});
- UNIT_ASSERT(i128{-3} <= i128{-2});
- UNIT_ASSERT(i128{-42} <= i128{-1});
- UNIT_ASSERT(i128{-142} <= i128{42});
- i128 big = -i128{1, 0};
- UNIT_ASSERT(big <= i128{-1});
- UNIT_ASSERT(std::numeric_limits<i128>::min() <= i128{-1});
- }
-}
+
+#include <util/generic/cast.h>
+
+Y_UNIT_TEST_SUITE(I128ComparisonPositiveWithPositiveSuite) {
+ Y_UNIT_TEST(PositivePositiveGreater) {
+ UNIT_ASSERT(i128{1} > i128{0});
+ UNIT_ASSERT(i128{2} > i128{1});
+ UNIT_ASSERT(i128{42} > i128{0});
+ UNIT_ASSERT(i128{42} > i128{1});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(big > i128{1});
+ UNIT_ASSERT(std::numeric_limits<i128>::max() > i128{0});
+ }
+
+ Y_UNIT_TEST(PositivePositiveGreaterOrEqual) {
+ UNIT_ASSERT(i128{1} >= i128{0});
+ UNIT_ASSERT(i128{2} >= i128{1});
+ UNIT_ASSERT(i128{42} >= i128{0});
+ UNIT_ASSERT(i128{42} >= i128{1});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(big >= i128{1});
+ UNIT_ASSERT(std::numeric_limits<i128>::max() >= i128{0});
+
+ UNIT_ASSERT(i128{0} >= i128{0});
+ UNIT_ASSERT(i128{1} >= i128{1});
+ UNIT_ASSERT(i128{2} >= i128{2});
+ UNIT_ASSERT(i128{42} >= i128{42});
+ UNIT_ASSERT(big >= big);
+ UNIT_ASSERT(std::numeric_limits<i128>::max() >= std::numeric_limits<i128>::max());
+ }
+
+ Y_UNIT_TEST(PositivePositiveLess) {
+ UNIT_ASSERT(i128{0} < i128{1});
+ UNIT_ASSERT(i128{1} < i128{2});
+ UNIT_ASSERT(i128{0} < i128{42});
+ UNIT_ASSERT(i128{1} < i128{42});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(i128{1} < big);
+ UNIT_ASSERT(i128{0} < std::numeric_limits<i128>::max());
+ }
+
+ Y_UNIT_TEST(PositivePositiveLessOrEqual) {
+ UNIT_ASSERT(i128{0} <= i128{1});
+ UNIT_ASSERT(i128{1} <= i128{2});
+ UNIT_ASSERT(i128{0} <= i128{42});
+ UNIT_ASSERT(i128{1} <= i128{42});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(i128{1} <= big);
+ UNIT_ASSERT(i128{0} <= std::numeric_limits<i128>::max());
+
+ UNIT_ASSERT(i128{0} <= i128{0});
+ UNIT_ASSERT(i128{1} <= i128{1});
+ UNIT_ASSERT(i128{2} <= i128{2});
+ UNIT_ASSERT(i128{42} <= i128{42});
+ UNIT_ASSERT(big <= big);
+ UNIT_ASSERT(std::numeric_limits<i128>::max() <= std::numeric_limits<i128>::max());
+ }
+}
+
+Y_UNIT_TEST_SUITE(I128ComparisonPositiveWithNegativeSuite) {
+ Y_UNIT_TEST(PositiveNegativeGreater) {
+ UNIT_ASSERT(i128{0} > i128{-1});
+ UNIT_ASSERT(i128{2} > i128{-1});
+ UNIT_ASSERT(i128{0} > i128{-42});
+ UNIT_ASSERT(i128{42} > i128{-1});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(big > i128{-1});
+ UNIT_ASSERT(std::numeric_limits<i128>::max() > i128{-1});
+ }
+
+ Y_UNIT_TEST(PositiveNegativeGreaterOrEqual) {
+ UNIT_ASSERT(i128{0} >= i128{-1});
+ UNIT_ASSERT(i128{2} >= i128{-1});
+ UNIT_ASSERT(i128{0} >= i128{-42});
+ UNIT_ASSERT(i128{42} >= i128{-1});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(big >= i128{-1});
+ UNIT_ASSERT(std::numeric_limits<i128>::max() >= i128{-1});
+ }
+
+ Y_UNIT_TEST(NegativePositiveLess) {
+ UNIT_ASSERT(i128{-1} < i128{0});
+ UNIT_ASSERT(i128{-1} < i128{2});
+ UNIT_ASSERT(i128{-42} < i128{0});
+ UNIT_ASSERT(i128{-1} < i128{42});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(i128{-1} < big);
+ UNIT_ASSERT(i128{-1} < std::numeric_limits<i128>::max());
+ }
+
+ Y_UNIT_TEST(NegativePositiveLessOrEqual) {
+ UNIT_ASSERT(i128{-1} <= i128{0});
+ UNIT_ASSERT(i128{-1} <= i128{2});
+ UNIT_ASSERT(i128{-42} <= i128{0});
+ UNIT_ASSERT(i128{-1} <= i128{42});
+ i128 big = i128{1, 0};
+ UNIT_ASSERT(i128{-1} <= big);
+ UNIT_ASSERT(i128{-1} <= std::numeric_limits<i128>::max());
+ }
+}
+
+Y_UNIT_TEST_SUITE(I128ComparisonNegativeWithNegativeSuite) {
+ Y_UNIT_TEST(NegativeNegativeGreater) {
+ UNIT_ASSERT(i128{-1} > i128{-2});
+ UNIT_ASSERT(i128{-2} > i128{-3});
+ UNIT_ASSERT(i128{-1} > i128{-42});
+ UNIT_ASSERT(i128{-42} > i128{-142});
+ i128 big = -i128{1, 0};
+ UNIT_ASSERT(i128{-1} > big);
+ UNIT_ASSERT(i128{-1} > std::numeric_limits<i128>::min());
+ }
+
+ Y_UNIT_TEST(NegativeNegativeGreaterOrEqual) {
+ UNIT_ASSERT(i128{-1} >= i128{-2});
+ UNIT_ASSERT(i128{-2} >= i128{-3});
+ UNIT_ASSERT(i128{-1} >= i128{-42});
+ UNIT_ASSERT(i128{-42} >= i128{-142});
+ i128 big = -i128{1, 0};
+ UNIT_ASSERT(i128{-1} >= big);
+ UNIT_ASSERT(i128{-1} >= std::numeric_limits<i128>::min());
+ }
+
+ Y_UNIT_TEST(NegativeNegativeLess) {
+ UNIT_ASSERT(i128{-2} < i128{-1});
+ UNIT_ASSERT(i128{-3} < i128{-2});
+ UNIT_ASSERT(i128{-42} < i128{-1});
+ UNIT_ASSERT(i128{-142} < i128{42});
+ i128 big = -i128{1, 0};
+ UNIT_ASSERT(big < i128{-1});
+ UNIT_ASSERT(std::numeric_limits<i128>::min() < i128{-1});
+ }
+
+ Y_UNIT_TEST(NegativeNegativeLessOrEqual) {
+ UNIT_ASSERT(i128{-2} <= i128{-1});
+ UNIT_ASSERT(i128{-3} <= i128{-2});
+ UNIT_ASSERT(i128{-42} <= i128{-1});
+ UNIT_ASSERT(i128{-142} <= i128{42});
+ i128 big = -i128{1, 0};
+ UNIT_ASSERT(big <= i128{-1});
+ UNIT_ASSERT(std::numeric_limits<i128>::min() <= i128{-1});
+ }
+}
diff --git a/library/cpp/int128/ut/i128_division_ut.cpp b/library/cpp/int128/ut/i128_division_ut.cpp
index 46b0ca27f5..b58731dd7e 100644
--- a/library/cpp/int128/ut/i128_division_ut.cpp
+++ b/library/cpp/int128/ut/i128_division_ut.cpp
@@ -1,413 +1,413 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-Y_UNIT_TEST_SUITE(I128DivisionBy1Suite) {
- Y_UNIT_TEST(I128Divide0By1) {
- i128 dividend = 0;
- i128 divider = 1;
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide1By1) {
- i128 dividend = 1;
- i128 divider = 1;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide2By1) {
- i128 dividend = 2;
- i128 divider = 1;
- i128 expectedQuotient = 2;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide42By1) {
- i128 dividend = 42;
- i128 divider = 1;
- i128 expectedQuotient = 42;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64By1) {
- i128 dividend = std::numeric_limits<ui64>::max();
- i128 divider = 1;
- i128 expectedQuotient = std::numeric_limits<ui64>::max();
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64Plus1By1) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 divider = 1;
- i128 expectedQuotient = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64Plus42By1) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{42};
- i128 divider = 1;
- i128 expectedQuotient = i128{std::numeric_limits<ui64>::max()} + i128{42};
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxI128By1) {
- i128 dividend = std::numeric_limits<i128>::max();
- i128 divider = 1;
- i128 expectedQuotient = std::numeric_limits<i128>::max();
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxI128Minus1By1) {
- i128 dividend = std::numeric_limits<i128>::max() - 1;
- i128 divider = 1;
- i128 expectedQuotient = std::numeric_limits<i128>::max() - 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(I128DivisionByEqualSuite) {
- Y_UNIT_TEST(I128Divide1ByEqual) {
- i128 dividend = 1;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide2ByEqual) {
- i128 dividend = 2;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide42ByEqual) {
- i128 dividend = 42;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64ByEqual) {
- i128 dividend = std::numeric_limits<ui64>::max();
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64Plus1ByEqual) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64Plus42ByEqual) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{42};
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxI128ByEqual) {
- i128 dividend = std::numeric_limits<i128>::max();
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxI128Minus1ByEqual) {
- i128 dividend = std::numeric_limits<i128>::max() - 1;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(I128DivisionLessByHigherSuite) {
- Y_UNIT_TEST(I128Divide42By84) {
- i128 dividend = 42;
- i128 divider = 84;
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 42;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide42ByMaxUi64) {
- i128 dividend = 42;
- i128 divider = std::numeric_limits<ui64>::max();
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 42;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128Divide42ByMaxUi64Plus1) {
- i128 dividend = 42;
- i128 divider = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 42;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(I128DivideMaxUi64ByMaxUi64Plus1) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()};
- i128 divider = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 expectedQuotient = 0;
- i128 expectedRemainder = i128{std::numeric_limits<ui64>::max()};
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(I128DivisionWithDifferentSigns) {
- Y_UNIT_TEST(DivisionPositiveByNegative) {
- i128 dividend = i128{100};
- i128 divider = i128{-33};
- i128 expectedQuotient = -3;
- i128 expectedRemainder = 1;
- i128 quotient = dividend / divider;
- i128 remainder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
- }
-
- Y_UNIT_TEST(DivisionNegativeByPositive) {
- i128 dividend = i128{-100};
- i128 divider = i128{33};
- i128 expectedQuotient = -3;
- i128 expectedRemainder = -1;
- i128 quotient = dividend / divider;
- i128 remainder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
- }
-
- Y_UNIT_TEST(DivisionNegativeByNegative) {
- i128 dividend = i128{-100};
- i128 divider = i128{-33};
- i128 expectedQuotient = 3;
- i128 expectedRemainder = -1;
- i128 quotient = dividend / divider;
- i128 remainder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(i128DivisionBigByBigSuite) {
- Y_UNIT_TEST(i128DivideBigByBig1) {
- i128 dividend = {64, 0};
- i128 divider = {1, 0};
- i128 expectedQuotient = 64;
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig1_PosByNeg) {
- i128 dividend = i128{64, 0};
- i128 divider = -i128{1, 0};
- i128 expectedQuotient = -i128{64};
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig1_NegByPos) {
- i128 dividend = -i128{64, 0};
- i128 divider = i128{1, 0};
- i128 expectedQuotient = -i128{64};
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig1_NegByNeg) {
- i128 dividend = -i128{64, 0};
- i128 divider = -i128{1, 0};
- i128 expectedQuotient = i128{64};
- i128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig2) {
- i128 dividend = {64, 0};
- i128 divider = {12, 5};
- i128 expectedQuotient = 5;
- i128 expectedRemainder = i128{3, 18446744073709551591ull}; // plz don't ask
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig2_PosByNeg) {
- i128 dividend = i128{64, 0};
- i128 divider = -i128{12, 5};
- i128 expectedQuotient = -5;
- i128 expectedRemainder = i128{3, 18446744073709551591ull};
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig2_NegByPos) {
- i128 dividend = -i128{64, 0};
- i128 divider = i128{12, 5};
- i128 expectedQuotient = -5;
- i128 expectedRemainder = -i128{3, 18446744073709551591ull};
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(i128DivideBigByBig2_NegByNeg) {
- i128 dividend = -i128{64, 0};
- i128 divider = -i128{12, 5};
- i128 expectedQuotient = 5;
- i128 expectedRemainder = -i128{3, 18446744073709551591ull};
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
-}
-
-Y_UNIT_TEST_SUITE(i128DivisionAlgo) {
- Y_UNIT_TEST(ii128DivideAlgoCheck_PosByPos) {
- /*
- 49672666804009505000000 / 10000000 == 4967266680400950
- 49672666804009505000000 % 10000000 == 5000000
- */
- i128 dividend = {2692ull, 14031757583392049728ull};
- i64 divider = 10000000;
- i128 expectedQuotient = {0, 4967266680400950ull};
- i128 expectedRemainder = {0, 5000000ull};
-
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
-
- Y_UNIT_TEST(ii128DivideAlgoCheck_PosByNeg) {
- /*
- 49672666804009505000000 / -10000000 == -4967266680400950
- 49672666804009505000000 % -10000000 == 5000000
- */
- i128 dividend = {2692ull, 14031757583392049728ull};
- i64 divider = -10000000;
- i128 expectedQuotient = -i128{0, 4967266680400950ull};
- i128 expectedRemainder = {0, 5000000ull};
-
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
-
- Y_UNIT_TEST(ii128DivideAlgoCheck_NegByPos) {
- /*
- -49672666804009505000000 / 10000000 == -4967266680400950
- -49672666804009505000000 % 10000000 == -5000000
- */
- i128 dividend = -i128{2692ull, 14031757583392049728ull};
- i64 divider = 10000000;
- i128 expectedQuotient = -i128{0, 4967266680400950ull};
- i128 expectedRemainder = -i128{0, 5000000ull};
-
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
-
- Y_UNIT_TEST(ii128DivideAlgoCheck_NegByNeg) {
- /*
- -49672666804009505000000 / -10000000 == 4967266680400950
- -49672666804009505000000 % -10000000 == -5000000
- */
- i128 dividend = -i128{2692ull, 14031757583392049728ull};
- i64 divider = -10000000;
- i128 expectedQuotient = {0, 4967266680400950ull};
- i128 expectedRemainder = -i128{0, 5000000ull};
-
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
-
-}
+
+#include <util/generic/cast.h>
+
+Y_UNIT_TEST_SUITE(I128DivisionBy1Suite) {
+ Y_UNIT_TEST(I128Divide0By1) {
+ i128 dividend = 0;
+ i128 divider = 1;
+ i128 expectedQuotient = 0;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide1By1) {
+ i128 dividend = 1;
+ i128 divider = 1;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide2By1) {
+ i128 dividend = 2;
+ i128 divider = 1;
+ i128 expectedQuotient = 2;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide42By1) {
+ i128 dividend = 42;
+ i128 divider = 1;
+ i128 expectedQuotient = 42;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64By1) {
+ i128 dividend = std::numeric_limits<ui64>::max();
+ i128 divider = 1;
+ i128 expectedQuotient = std::numeric_limits<ui64>::max();
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64Plus1By1) {
+ i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{1};
+ i128 divider = 1;
+ i128 expectedQuotient = i128{std::numeric_limits<ui64>::max()} + i128{1};
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64Plus42By1) {
+ i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{42};
+ i128 divider = 1;
+ i128 expectedQuotient = i128{std::numeric_limits<ui64>::max()} + i128{42};
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxI128By1) {
+ i128 dividend = std::numeric_limits<i128>::max();
+ i128 divider = 1;
+ i128 expectedQuotient = std::numeric_limits<i128>::max();
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxI128Minus1By1) {
+ i128 dividend = std::numeric_limits<i128>::max() - 1;
+ i128 divider = 1;
+ i128 expectedQuotient = std::numeric_limits<i128>::max() - 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(I128DivisionByEqualSuite) {
+ Y_UNIT_TEST(I128Divide1ByEqual) {
+ i128 dividend = 1;
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide2ByEqual) {
+ i128 dividend = 2;
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide42ByEqual) {
+ i128 dividend = 42;
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64ByEqual) {
+ i128 dividend = std::numeric_limits<ui64>::max();
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64Plus1ByEqual) {
+ i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{1};
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64Plus42ByEqual) {
+ i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{42};
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxI128ByEqual) {
+ i128 dividend = std::numeric_limits<i128>::max();
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxI128Minus1ByEqual) {
+ i128 dividend = std::numeric_limits<i128>::max() - 1;
+ i128 divider = dividend;
+ i128 expectedQuotient = 1;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(I128DivisionLessByHigherSuite) {
+ Y_UNIT_TEST(I128Divide42By84) {
+ i128 dividend = 42;
+ i128 divider = 84;
+ i128 expectedQuotient = 0;
+ i128 expectedRemainder = 42;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide42ByMaxUi64) {
+ i128 dividend = 42;
+ i128 divider = std::numeric_limits<ui64>::max();
+ i128 expectedQuotient = 0;
+ i128 expectedRemainder = 42;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128Divide42ByMaxUi64Plus1) {
+ i128 dividend = 42;
+ i128 divider = i128{std::numeric_limits<ui64>::max()} + i128{1};
+ i128 expectedQuotient = 0;
+ i128 expectedRemainder = 42;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(I128DivideMaxUi64ByMaxUi64Plus1) {
+ i128 dividend = i128{std::numeric_limits<ui64>::max()};
+ i128 divider = i128{std::numeric_limits<ui64>::max()} + i128{1};
+ i128 expectedQuotient = 0;
+ i128 expectedRemainder = i128{std::numeric_limits<ui64>::max()};
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(I128DivisionWithDifferentSigns) {
+ Y_UNIT_TEST(DivisionPositiveByNegative) {
+ i128 dividend = i128{100};
+ i128 divider = i128{-33};
+ i128 expectedQuotient = -3;
+ i128 expectedRemainder = 1;
+ i128 quotient = dividend / divider;
+ i128 remainder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(DivisionNegativeByPositive) {
+ i128 dividend = i128{-100};
+ i128 divider = i128{33};
+ i128 expectedQuotient = -3;
+ i128 expectedRemainder = -1;
+ i128 quotient = dividend / divider;
+ i128 remainder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(DivisionNegativeByNegative) {
+ i128 dividend = i128{-100};
+ i128 divider = i128{-33};
+ i128 expectedQuotient = 3;
+ i128 expectedRemainder = -1;
+ i128 quotient = dividend / divider;
+ i128 remainder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(i128DivisionBigByBigSuite) {
+ Y_UNIT_TEST(i128DivideBigByBig1) {
+ i128 dividend = {64, 0};
+ i128 divider = {1, 0};
+ i128 expectedQuotient = 64;
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig1_PosByNeg) {
+ i128 dividend = i128{64, 0};
+ i128 divider = -i128{1, 0};
+ i128 expectedQuotient = -i128{64};
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig1_NegByPos) {
+ i128 dividend = -i128{64, 0};
+ i128 divider = i128{1, 0};
+ i128 expectedQuotient = -i128{64};
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig1_NegByNeg) {
+ i128 dividend = -i128{64, 0};
+ i128 divider = -i128{1, 0};
+ i128 expectedQuotient = i128{64};
+ i128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig2) {
+ i128 dividend = {64, 0};
+ i128 divider = {12, 5};
+ i128 expectedQuotient = 5;
+ i128 expectedRemainder = i128{3, 18446744073709551591ull}; // plz don't ask
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig2_PosByNeg) {
+ i128 dividend = i128{64, 0};
+ i128 divider = -i128{12, 5};
+ i128 expectedQuotient = -5;
+ i128 expectedRemainder = i128{3, 18446744073709551591ull};
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig2_NegByPos) {
+ i128 dividend = -i128{64, 0};
+ i128 divider = i128{12, 5};
+ i128 expectedQuotient = -5;
+ i128 expectedRemainder = -i128{3, 18446744073709551591ull};
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(i128DivideBigByBig2_NegByNeg) {
+ i128 dividend = -i128{64, 0};
+ i128 divider = -i128{12, 5};
+ i128 expectedQuotient = 5;
+ i128 expectedRemainder = -i128{3, 18446744073709551591ull};
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+}
+
+Y_UNIT_TEST_SUITE(i128DivisionAlgo) {
+ Y_UNIT_TEST(ii128DivideAlgoCheck_PosByPos) {
+ /*
+ 49672666804009505000000 / 10000000 == 4967266680400950
+ 49672666804009505000000 % 10000000 == 5000000
+ */
+ i128 dividend = {2692ull, 14031757583392049728ull};
+ i64 divider = 10000000;
+ i128 expectedQuotient = {0, 4967266680400950ull};
+ i128 expectedRemainder = {0, 5000000ull};
+
+ i128 quotient = dividend / divider;
+ i128 reminder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(ii128DivideAlgoCheck_PosByNeg) {
+ /*
+ 49672666804009505000000 / -10000000 == -4967266680400950
+ 49672666804009505000000 % -10000000 == 5000000
+ */
+ i128 dividend = {2692ull, 14031757583392049728ull};
+ i64 divider = -10000000;
+ i128 expectedQuotient = -i128{0, 4967266680400950ull};
+ i128 expectedRemainder = {0, 5000000ull};
+
+ i128 quotient = dividend / divider;
+ i128 reminder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(ii128DivideAlgoCheck_NegByPos) {
+ /*
+ -49672666804009505000000 / 10000000 == -4967266680400950
+ -49672666804009505000000 % 10000000 == -5000000
+ */
+ i128 dividend = -i128{2692ull, 14031757583392049728ull};
+ i64 divider = 10000000;
+ i128 expectedQuotient = -i128{0, 4967266680400950ull};
+ i128 expectedRemainder = -i128{0, 5000000ull};
+
+ i128 quotient = dividend / divider;
+ i128 reminder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(ii128DivideAlgoCheck_NegByNeg) {
+ /*
+ -49672666804009505000000 / -10000000 == 4967266680400950
+ -49672666804009505000000 % -10000000 == -5000000
+ */
+ i128 dividend = -i128{2692ull, 14031757583392049728ull};
+ i64 divider = -10000000;
+ i128 expectedQuotient = {0, 4967266680400950ull};
+ i128 expectedRemainder = -i128{0, 5000000ull};
+
+ i128 quotient = dividend / divider;
+ i128 reminder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
+ }
+
+}
diff --git a/library/cpp/int128/ut/i128_type_traits_ut.cpp b/library/cpp/int128/ut/i128_type_traits_ut.cpp
index 4ed87bf229..87a49ad985 100644
--- a/library/cpp/int128/ut/i128_type_traits_ut.cpp
+++ b/library/cpp/int128/ut/i128_type_traits_ut.cpp
@@ -1,68 +1,68 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-Y_UNIT_TEST_SUITE(I128TypeTraitsSuite) {
- Y_UNIT_TEST(OperatorNegate0) {
- const i128 n = 0;
- const i128 m = -n;
- UNIT_ASSERT(n == m);
- }
-
- Y_UNIT_TEST(OperatorNegate1) {
- const i128 n = 1;
- const i128 m = -n;
- const i128 expected = -1;
- UNIT_ASSERT(m == expected);
- }
-
- Y_UNIT_TEST(OperatorNegate2Pow64) {
- const i128 n = i128{1, 0};
- const i128 m = -n;
- const i128 expected = {static_cast<ui64>(-1), 0};
- UNIT_ASSERT(m == expected);
- }
-
- Y_UNIT_TEST(OperatorNegateNegate) {
- const i128 x = 1;
- const i128 y = -x;
- const i128 z = -y;
- UNIT_ASSERT(z == x);
- }
-
- Y_UNIT_TEST(AbsFromPositive) {
- const i128 n = 1;
- const i128 m = std::abs(n);
- UNIT_ASSERT(m == n);
- }
-
- Y_UNIT_TEST(AbsFromNegative) {
- const i128 n = -1;
- const i128 m = std::abs(n);
- const i128 expected = 1;
- UNIT_ASSERT(m == expected);
- }
-
- Y_UNIT_TEST(AbsFromZero) {
- const i128 n = 0;
- const i128 m = std::abs(n);
- UNIT_ASSERT(m == n);
- }
-
- Y_UNIT_TEST(SignbitOfPositive) {
- const i128 n = 1;
- UNIT_ASSERT(!std::signbit(n));
- }
-
- Y_UNIT_TEST(SignbitOfNegative) {
- const i128 n = -1;
- UNIT_ASSERT(std::signbit(n));
- }
-
- Y_UNIT_TEST(SignbitOfZero) {
- const i128 n = 0;
- UNIT_ASSERT(!std::signbit(n));
- }
-}
+
+#include <util/generic/cast.h>
+
+Y_UNIT_TEST_SUITE(I128TypeTraitsSuite) {
+ Y_UNIT_TEST(OperatorNegate0) {
+ const i128 n = 0;
+ const i128 m = -n;
+ UNIT_ASSERT(n == m);
+ }
+
+ Y_UNIT_TEST(OperatorNegate1) {
+ const i128 n = 1;
+ const i128 m = -n;
+ const i128 expected = -1;
+ UNIT_ASSERT(m == expected);
+ }
+
+ Y_UNIT_TEST(OperatorNegate2Pow64) {
+ const i128 n = i128{1, 0};
+ const i128 m = -n;
+ const i128 expected = {static_cast<ui64>(-1), 0};
+ UNIT_ASSERT(m == expected);
+ }
+
+ Y_UNIT_TEST(OperatorNegateNegate) {
+ const i128 x = 1;
+ const i128 y = -x;
+ const i128 z = -y;
+ UNIT_ASSERT(z == x);
+ }
+
+ Y_UNIT_TEST(AbsFromPositive) {
+ const i128 n = 1;
+ const i128 m = std::abs(n);
+ UNIT_ASSERT(m == n);
+ }
+
+ Y_UNIT_TEST(AbsFromNegative) {
+ const i128 n = -1;
+ const i128 m = std::abs(n);
+ const i128 expected = 1;
+ UNIT_ASSERT(m == expected);
+ }
+
+ Y_UNIT_TEST(AbsFromZero) {
+ const i128 n = 0;
+ const i128 m = std::abs(n);
+ UNIT_ASSERT(m == n);
+ }
+
+ Y_UNIT_TEST(SignbitOfPositive) {
+ const i128 n = 1;
+ UNIT_ASSERT(!std::signbit(n));
+ }
+
+ Y_UNIT_TEST(SignbitOfNegative) {
+ const i128 n = -1;
+ UNIT_ASSERT(std::signbit(n));
+ }
+
+ Y_UNIT_TEST(SignbitOfZero) {
+ const i128 n = 0;
+ UNIT_ASSERT(!std::signbit(n));
+ }
+}
diff --git a/library/cpp/int128/ut/i128_ut.cpp b/library/cpp/int128/ut/i128_ut.cpp
index c196d132a2..39408d4d37 100644
--- a/library/cpp/int128/ut/i128_ut.cpp
+++ b/library/cpp/int128/ut/i128_ut.cpp
@@ -1,12 +1,12 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-Y_UNIT_TEST_SUITE(I128Suite) {
- Y_UNIT_TEST(CreateI128FromUnsigned) {
- i128 v{ui64(1)};
- Y_UNUSED(v);
- }
-}
+
+#include <util/generic/cast.h>
+
+Y_UNIT_TEST_SUITE(I128Suite) {
+ Y_UNIT_TEST(CreateI128FromUnsigned) {
+ i128 v{ui64(1)};
+ Y_UNUSED(v);
+ }
+}
diff --git a/library/cpp/int128/ut/int128_old_ut.cpp b/library/cpp/int128/ut/int128_old_ut.cpp
index 2c5b9e9610..e8dfbff5c2 100644
--- a/library/cpp/int128/ut/int128_old_ut.cpp
+++ b/library/cpp/int128/ut/int128_old_ut.cpp
@@ -1,8 +1,8 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/int128/int128.h>
-#include "int128_ut_helpers.h"
-
+#include "int128_ut_helpers.h"
+
class TUInt128Test: public TTestBase {
UNIT_TEST_SUITE(TUInt128Test);
UNIT_TEST(Create);
@@ -13,9 +13,9 @@ class TUInt128Test: public TTestBase {
UNIT_TEST(Underflow);
UNIT_TEST(ToStringTest);
UNIT_TEST(FromStringTest);
-#if defined(Y_HAVE_INT128)
+#if defined(Y_HAVE_INT128)
UNIT_TEST(FromSystemUint128);
-#endif
+#endif
UNIT_TEST_SUITE_END();
private:
@@ -25,30 +25,30 @@ private:
void Shift();
void Overflow();
void Underflow();
- void ToStringTest();
- void FromStringTest();
-#if defined(Y_HAVE_INT128)
- void FromSystemUint128();
-#endif
+ void ToStringTest();
+ void FromStringTest();
+#if defined(Y_HAVE_INT128)
+ void FromSystemUint128();
+#endif
};
UNIT_TEST_SUITE_REGISTRATION(TUInt128Test);
void TUInt128Test::Create() {
- const ui128 n1 = 10;
+ const ui128 n1 = 10;
UNIT_ASSERT_EQUAL(n1, 10);
- const ui128 n2 = n1;
+ const ui128 n2 = n1;
UNIT_ASSERT_EQUAL(n2, 10);
- const ui128 n3(10);
+ const ui128 n3(10);
UNIT_ASSERT_EQUAL(n3, 10);
}
void TUInt128Test::Minus() {
- const ui128 n2 = 20;
- const ui128 n3 = 30;
+ const ui128 n2 = 20;
+ const ui128 n3 = 30;
- ui128 n4 = n3 - n2;
+ ui128 n4 = n3 - n2;
UNIT_ASSERT_EQUAL(n4, 10);
n4 = n4 - 2;
@@ -61,10 +61,10 @@ void TUInt128Test::Minus() {
UNIT_ASSERT_EQUAL(n4, 4);
}
void TUInt128Test::Plus() {
- const ui128 n2 = 20;
- const ui128 n3 = 30;
+ const ui128 n2 = 20;
+ const ui128 n3 = 30;
- ui128 n4 = n3 + n2;
+ ui128 n4 = n3 + n2;
UNIT_ASSERT_EQUAL(n4, 50);
n4 = n4 + 2;
@@ -77,103 +77,103 @@ void TUInt128Test::Plus() {
UNIT_ASSERT_EQUAL(n4, 64);
}
void TUInt128Test::Shift() {
- ui128 n = 1;
+ ui128 n = 1;
- const ui128 n4 = n << 4;
- UNIT_ASSERT_EQUAL(n4, ui128(0x0, 0x0000000000000010));
+ const ui128 n4 = n << 4;
+ UNIT_ASSERT_EQUAL(n4, ui128(0x0, 0x0000000000000010));
UNIT_ASSERT_EQUAL(n4 >> 4, 1);
- const ui128 n8 = n << 8;
- UNIT_ASSERT_EQUAL(n8, ui128(0x0, 0x0000000000000100));
+ const ui128 n8 = n << 8;
+ UNIT_ASSERT_EQUAL(n8, ui128(0x0, 0x0000000000000100));
UNIT_ASSERT_EQUAL(n8 >> 8, 1);
- const ui128 n60 = n << 60;
- UNIT_ASSERT_EQUAL(n60, ui128(0x0, 0x1000000000000000));
+ const ui128 n60 = n << 60;
+ UNIT_ASSERT_EQUAL(n60, ui128(0x0, 0x1000000000000000));
UNIT_ASSERT_EQUAL(n60 >> 60, 1);
- const ui128 n64 = n << 64;
- UNIT_ASSERT_EQUAL(n64, ui128(0x1, 0x0000000000000000));
+ const ui128 n64 = n << 64;
+ UNIT_ASSERT_EQUAL(n64, ui128(0x1, 0x0000000000000000));
UNIT_ASSERT_EQUAL(n64 >> 64, 1);
- const ui128 n124 = n << 124;
- UNIT_ASSERT_EQUAL(n124, ui128(0x1000000000000000, 0x0000000000000000));
+ const ui128 n124 = n << 124;
+ UNIT_ASSERT_EQUAL(n124, ui128(0x1000000000000000, 0x0000000000000000));
UNIT_ASSERT_EQUAL(n124 >> 124, 1);
}
void TUInt128Test::Overflow() {
- ui128 n = ui128(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
- const ui128 n2 = n + 2;
+ ui128 n = ui128(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
+ const ui128 n2 = n + 2;
UNIT_ASSERT_EQUAL(n2, 1);
}
void TUInt128Test::Underflow() {
- ui128 n = 1;
- const ui128 n128 = n - 2;
- UNIT_ASSERT_EQUAL(n128, ui128(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF));
-}
-
-void TUInt128Test::ToStringTest() {
- ui128 n(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
- TString correct = "340282366920938463463374607431768211455";
- UNIT_ASSERT_EQUAL(correct, ::ToString(n));
-}
-
-void TUInt128Test::FromStringTest() {
- {
- const TString originalString = "37778931862957161709568";
- const ui128 number = FromString<ui128>(originalString);
- UNIT_ASSERT_EQUAL(ToString(number), originalString);
- }
-
- {
- const TString originalString = "1024";
- const ui128 number = FromString<ui128>(originalString);
- UNIT_ASSERT_EQUAL(ToString(number), originalString);
- UNIT_ASSERT_EQUAL(GetHigh(number), 0);
- UNIT_ASSERT_EQUAL(GetLow(number), 1024);
- }
-
- {
- const TString originalString = "18446744073709551616"; // 2^64, i.e. UINT64_MAX + 1
- const ui128 number = FromString<ui128>(originalString);
- UNIT_ASSERT_EQUAL(ToString(number), originalString);
- UNIT_ASSERT_EQUAL(GetHigh(number), 1);
- UNIT_ASSERT_EQUAL(GetLow(number), 0);
- }
-
- {
- const TString originalString = "340282366920938463463374607431768211455"; // 2^128-1, i.e. UINT128_MAX
- const ui128 number = FromString<ui128>(originalString);
- UNIT_ASSERT_EQUAL(ToString(number), originalString);
- UNIT_ASSERT_EQUAL(GetHigh(number), 0xFFFFFFFFFFFFFFFF);
- UNIT_ASSERT_EQUAL(GetLow(number), 0xFFFFFFFFFFFFFFFF);
- }
-}
-
-#if defined(Y_HAVE_INT128)
-void TUInt128Test::FromSystemUint128() {
- unsigned __int128 n = 1;
- ui128 number{n};
-
- UNIT_ASSERT_EQUAL(GetLow(number), 1);
- UNIT_ASSERT_EQUAL(GetHigh(number), 0);
-
- auto byteArray = NInt128Private::GetAsArray(number);
-#ifdef _little_endian_
- UNIT_ASSERT_EQUAL(byteArray[0], 1);
- for (size_t i = 1; i < 16; i++) {
- UNIT_ASSERT_EQUAL(byteArray[i], 0);
- }
-#elif defined(_big_endian_)
- UNIT_ASSERT_EQUAL(byteArray[15], 1);
- for (size_t i = 0; i < 15; i++) {
- UNIT_ASSERT_EQUAL(byteArray[i], 0);
- }
-#endif
-
- UNIT_ASSERT_EQUAL(std::memcmp((void*)&n, (void*)&number, 16), 0);
-
- UNIT_ASSERT_EQUAL(ToString(n), "1");
-
- UNIT_ASSERT_EQUAL(FromString<unsigned __int128>(ToString(n)), n);
+ ui128 n = 1;
+ const ui128 n128 = n - 2;
+ UNIT_ASSERT_EQUAL(n128, ui128(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF));
}
-#endif
+
+void TUInt128Test::ToStringTest() {
+ ui128 n(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
+ TString correct = "340282366920938463463374607431768211455";
+ UNIT_ASSERT_EQUAL(correct, ::ToString(n));
+}
+
+void TUInt128Test::FromStringTest() {
+ {
+ const TString originalString = "37778931862957161709568";
+ const ui128 number = FromString<ui128>(originalString);
+ UNIT_ASSERT_EQUAL(ToString(number), originalString);
+ }
+
+ {
+ const TString originalString = "1024";
+ const ui128 number = FromString<ui128>(originalString);
+ UNIT_ASSERT_EQUAL(ToString(number), originalString);
+ UNIT_ASSERT_EQUAL(GetHigh(number), 0);
+ UNIT_ASSERT_EQUAL(GetLow(number), 1024);
+ }
+
+ {
+ const TString originalString = "18446744073709551616"; // 2^64, i.e. UINT64_MAX + 1
+ const ui128 number = FromString<ui128>(originalString);
+ UNIT_ASSERT_EQUAL(ToString(number), originalString);
+ UNIT_ASSERT_EQUAL(GetHigh(number), 1);
+ UNIT_ASSERT_EQUAL(GetLow(number), 0);
+ }
+
+ {
+ const TString originalString = "340282366920938463463374607431768211455"; // 2^128-1, i.e. UINT128_MAX
+ const ui128 number = FromString<ui128>(originalString);
+ UNIT_ASSERT_EQUAL(ToString(number), originalString);
+ UNIT_ASSERT_EQUAL(GetHigh(number), 0xFFFFFFFFFFFFFFFF);
+ UNIT_ASSERT_EQUAL(GetLow(number), 0xFFFFFFFFFFFFFFFF);
+ }
+}
+
+#if defined(Y_HAVE_INT128)
+void TUInt128Test::FromSystemUint128() {
+ unsigned __int128 n = 1;
+ ui128 number{n};
+
+ UNIT_ASSERT_EQUAL(GetLow(number), 1);
+ UNIT_ASSERT_EQUAL(GetHigh(number), 0);
+
+ auto byteArray = NInt128Private::GetAsArray(number);
+#ifdef _little_endian_
+ UNIT_ASSERT_EQUAL(byteArray[0], 1);
+ for (size_t i = 1; i < 16; i++) {
+ UNIT_ASSERT_EQUAL(byteArray[i], 0);
+ }
+#elif defined(_big_endian_)
+ UNIT_ASSERT_EQUAL(byteArray[15], 1);
+ for (size_t i = 0; i < 15; i++) {
+ UNIT_ASSERT_EQUAL(byteArray[i], 0);
+ }
+#endif
+
+ UNIT_ASSERT_EQUAL(std::memcmp((void*)&n, (void*)&number, 16), 0);
+
+ UNIT_ASSERT_EQUAL(ToString(n), "1");
+
+ UNIT_ASSERT_EQUAL(FromString<unsigned __int128>(ToString(n)), n);
+}
+#endif
diff --git a/library/cpp/int128/ut/int128_typetraits_ut.cpp b/library/cpp/int128/ut/int128_typetraits_ut.cpp
index fd5f19d7b8..32be581dd0 100644
--- a/library/cpp/int128/ut/int128_typetraits_ut.cpp
+++ b/library/cpp/int128/ut/int128_typetraits_ut.cpp
@@ -1,306 +1,306 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <type_traits>
-
-Y_UNIT_TEST_SUITE(TypeTraitsSuite) {
- Y_UNIT_TEST(Uint128TypeTraits) {
- // checks that all type traits of ui128 are the same as of ui64
- // https://en.cppreference.com/w/cpp/header/type_traits
- UNIT_ASSERT_EQUAL(
- std::is_void<ui128>::value,
- std::is_void<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_null_pointer<ui128>::value,
- std::is_null_pointer<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_integral<ui128>::value,
- std::is_integral<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_floating_point<ui128>::value,
- std::is_floating_point<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_array<ui128>::value,
- std::is_array<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_enum<ui128>::value,
- std::is_enum<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_union<ui128>::value,
- std::is_union<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_class<ui128>::value,
- std::is_class<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_function<ui128>::value,
- std::is_function<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_pointer<ui128>::value,
- std::is_pointer<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_lvalue_reference<ui128>::value,
- std::is_lvalue_reference<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_rvalue_reference<ui128>::value,
- std::is_rvalue_reference<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_member_object_pointer<ui128>::value,
- std::is_member_object_pointer<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_member_function_pointer<ui128>::value,
- std::is_member_function_pointer<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_fundamental<ui128>::value,
- std::is_fundamental<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_arithmetic<ui128>::value,
- std::is_arithmetic<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_scalar<ui128>::value,
- std::is_scalar<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_object<ui128>::value,
- std::is_object<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_compound<ui128>::value,
- std::is_compound<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_reference<ui128>::value,
- std::is_reference<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_member_pointer<ui128>::value,
- std::is_member_pointer<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_const<ui128>::value,
- std::is_const<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_volatile<ui128>::value,
- std::is_volatile<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_trivial<ui128>::value,
- std::is_trivial<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_standard_layout<ui128>::value,
- std::is_standard_layout<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_pod<ui128>::value,
- std::is_pod<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_literal_type<ui128>::value,
- std::is_literal_type<ui64>::value
- );
-#ifndef _MSC_VER
- UNIT_ASSERT_EQUAL(
- std::has_unique_object_representations<ui128>::value,
- std::has_unique_object_representations<ui64>::value
- );
-#endif
- UNIT_ASSERT_EQUAL(
- std::is_empty<ui128>::value,
- std::is_empty<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_polymorphic<ui128>::value,
- std::is_polymorphic<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_abstract<ui128>::value,
- std::is_abstract<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_final<ui128>::value,
- std::is_final<ui64>::value
- );
-#ifndef _MSC_VER
- UNIT_ASSERT_EQUAL(
- std::is_aggregate<ui128>::value,
- std::is_aggregate<ui64>::value
- );
-#endif
- UNIT_ASSERT_EQUAL(
- std::is_signed<ui128>::value,
- std::is_signed<ui64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_unsigned<ui128>::value,
- std::is_unsigned<ui64>::value
- );
- }
-
- Y_UNIT_TEST(Int128TypeTraits) {
- // checks that all type traits of i128 are the same as of i64
- // https://en.cppreference.com/w/cpp/header/type_traits
- UNIT_ASSERT_EQUAL(
- std::is_void<i128>::value,
- std::is_void<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_null_pointer<i128>::value,
- std::is_null_pointer<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_integral<i128>::value,
- std::is_integral<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_floating_point<i128>::value,
- std::is_floating_point<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_array<i128>::value,
- std::is_array<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_enum<i128>::value,
- std::is_enum<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_union<i128>::value,
- std::is_union<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_class<i128>::value,
- std::is_class<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_function<i128>::value,
- std::is_function<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_pointer<i128>::value,
- std::is_pointer<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_lvalue_reference<i128>::value,
- std::is_lvalue_reference<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_rvalue_reference<i128>::value,
- std::is_rvalue_reference<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_member_object_pointer<i128>::value,
- std::is_member_object_pointer<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_member_function_pointer<i128>::value,
- std::is_member_function_pointer<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_fundamental<i128>::value,
- std::is_fundamental<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_arithmetic<i128>::value,
- std::is_arithmetic<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_scalar<i128>::value,
- std::is_scalar<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_object<i128>::value,
- std::is_object<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_compound<i128>::value,
- std::is_compound<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_reference<i128>::value,
- std::is_reference<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_member_pointer<i128>::value,
- std::is_member_pointer<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_const<i128>::value,
- std::is_const<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_volatile<i128>::value,
- std::is_volatile<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_trivial<i128>::value,
- std::is_trivial<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_standard_layout<i128>::value,
- std::is_standard_layout<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_pod<i128>::value,
- std::is_pod<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_literal_type<i128>::value,
- std::is_literal_type<i64>::value
- );
-#ifndef _MSC_VER
- UNIT_ASSERT_EQUAL(
- std::has_unique_object_representations<i128>::value,
- std::has_unique_object_representations<i64>::value
- );
-#endif
- UNIT_ASSERT_EQUAL(
- std::is_empty<i128>::value,
- std::is_empty<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_polymorphic<i128>::value,
- std::is_polymorphic<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_abstract<i128>::value,
- std::is_abstract<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_final<i128>::value,
- std::is_final<i64>::value
- );
-#ifndef _MSC_VER
- UNIT_ASSERT_EQUAL(
- std::is_aggregate<i128>::value,
- std::is_aggregate<i64>::value
- );
-#endif
- UNIT_ASSERT_EQUAL(
- std::is_signed<i128>::value,
- std::is_signed<i64>::value
- );
- UNIT_ASSERT_EQUAL(
- std::is_unsigned<i128>::value,
- std::is_unsigned<i64>::value
- );
- }
-}
-
+
+#include <type_traits>
+
+Y_UNIT_TEST_SUITE(TypeTraitsSuite) {
+ Y_UNIT_TEST(Uint128TypeTraits) {
+ // checks that all type traits of ui128 are the same as of ui64
+ // https://en.cppreference.com/w/cpp/header/type_traits
+ UNIT_ASSERT_EQUAL(
+ std::is_void<ui128>::value,
+ std::is_void<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_null_pointer<ui128>::value,
+ std::is_null_pointer<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_integral<ui128>::value,
+ std::is_integral<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_floating_point<ui128>::value,
+ std::is_floating_point<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_array<ui128>::value,
+ std::is_array<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_enum<ui128>::value,
+ std::is_enum<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_union<ui128>::value,
+ std::is_union<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_class<ui128>::value,
+ std::is_class<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_function<ui128>::value,
+ std::is_function<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_pointer<ui128>::value,
+ std::is_pointer<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_lvalue_reference<ui128>::value,
+ std::is_lvalue_reference<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_rvalue_reference<ui128>::value,
+ std::is_rvalue_reference<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_member_object_pointer<ui128>::value,
+ std::is_member_object_pointer<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_member_function_pointer<ui128>::value,
+ std::is_member_function_pointer<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_fundamental<ui128>::value,
+ std::is_fundamental<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_arithmetic<ui128>::value,
+ std::is_arithmetic<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_scalar<ui128>::value,
+ std::is_scalar<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_object<ui128>::value,
+ std::is_object<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_compound<ui128>::value,
+ std::is_compound<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_reference<ui128>::value,
+ std::is_reference<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_member_pointer<ui128>::value,
+ std::is_member_pointer<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_const<ui128>::value,
+ std::is_const<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_volatile<ui128>::value,
+ std::is_volatile<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_trivial<ui128>::value,
+ std::is_trivial<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_standard_layout<ui128>::value,
+ std::is_standard_layout<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_pod<ui128>::value,
+ std::is_pod<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_literal_type<ui128>::value,
+ std::is_literal_type<ui64>::value
+ );
+#ifndef _MSC_VER
+ UNIT_ASSERT_EQUAL(
+ std::has_unique_object_representations<ui128>::value,
+ std::has_unique_object_representations<ui64>::value
+ );
+#endif
+ UNIT_ASSERT_EQUAL(
+ std::is_empty<ui128>::value,
+ std::is_empty<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_polymorphic<ui128>::value,
+ std::is_polymorphic<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_abstract<ui128>::value,
+ std::is_abstract<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_final<ui128>::value,
+ std::is_final<ui64>::value
+ );
+#ifndef _MSC_VER
+ UNIT_ASSERT_EQUAL(
+ std::is_aggregate<ui128>::value,
+ std::is_aggregate<ui64>::value
+ );
+#endif
+ UNIT_ASSERT_EQUAL(
+ std::is_signed<ui128>::value,
+ std::is_signed<ui64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_unsigned<ui128>::value,
+ std::is_unsigned<ui64>::value
+ );
+ }
+
+ Y_UNIT_TEST(Int128TypeTraits) {
+ // checks that all type traits of i128 are the same as of i64
+ // https://en.cppreference.com/w/cpp/header/type_traits
+ UNIT_ASSERT_EQUAL(
+ std::is_void<i128>::value,
+ std::is_void<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_null_pointer<i128>::value,
+ std::is_null_pointer<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_integral<i128>::value,
+ std::is_integral<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_floating_point<i128>::value,
+ std::is_floating_point<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_array<i128>::value,
+ std::is_array<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_enum<i128>::value,
+ std::is_enum<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_union<i128>::value,
+ std::is_union<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_class<i128>::value,
+ std::is_class<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_function<i128>::value,
+ std::is_function<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_pointer<i128>::value,
+ std::is_pointer<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_lvalue_reference<i128>::value,
+ std::is_lvalue_reference<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_rvalue_reference<i128>::value,
+ std::is_rvalue_reference<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_member_object_pointer<i128>::value,
+ std::is_member_object_pointer<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_member_function_pointer<i128>::value,
+ std::is_member_function_pointer<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_fundamental<i128>::value,
+ std::is_fundamental<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_arithmetic<i128>::value,
+ std::is_arithmetic<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_scalar<i128>::value,
+ std::is_scalar<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_object<i128>::value,
+ std::is_object<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_compound<i128>::value,
+ std::is_compound<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_reference<i128>::value,
+ std::is_reference<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_member_pointer<i128>::value,
+ std::is_member_pointer<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_const<i128>::value,
+ std::is_const<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_volatile<i128>::value,
+ std::is_volatile<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_trivial<i128>::value,
+ std::is_trivial<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_standard_layout<i128>::value,
+ std::is_standard_layout<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_pod<i128>::value,
+ std::is_pod<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_literal_type<i128>::value,
+ std::is_literal_type<i64>::value
+ );
+#ifndef _MSC_VER
+ UNIT_ASSERT_EQUAL(
+ std::has_unique_object_representations<i128>::value,
+ std::has_unique_object_representations<i64>::value
+ );
+#endif
+ UNIT_ASSERT_EQUAL(
+ std::is_empty<i128>::value,
+ std::is_empty<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_polymorphic<i128>::value,
+ std::is_polymorphic<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_abstract<i128>::value,
+ std::is_abstract<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_final<i128>::value,
+ std::is_final<i64>::value
+ );
+#ifndef _MSC_VER
+ UNIT_ASSERT_EQUAL(
+ std::is_aggregate<i128>::value,
+ std::is_aggregate<i64>::value
+ );
+#endif
+ UNIT_ASSERT_EQUAL(
+ std::is_signed<i128>::value,
+ std::is_signed<i64>::value
+ );
+ UNIT_ASSERT_EQUAL(
+ std::is_unsigned<i128>::value,
+ std::is_unsigned<i64>::value
+ );
+ }
+}
+
diff --git a/library/cpp/int128/ut/int128_ut.cpp b/library/cpp/int128/ut/int128_ut.cpp
index 7339264017..0d68e42100 100644
--- a/library/cpp/int128/ut/int128_ut.cpp
+++ b/library/cpp/int128/ut/int128_ut.cpp
@@ -1,56 +1,56 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-#include <type_traits>
-
-Y_UNIT_TEST_SUITE(Uint128Suite) {
- Y_UNIT_TEST(Uint128DefaultCtor) {
- const ui128 value{};
- UNIT_ASSERT_EQUAL(GetLow(value), 0);
- UNIT_ASSERT_EQUAL(GetHigh(value), 0);
- }
-
- Y_UNIT_TEST(Uint128NumericLimits) {
- UNIT_ASSERT_EQUAL(std::numeric_limits<ui128>::digits, 128);
- UNIT_ASSERT_EQUAL(std::numeric_limits<ui128>::max() + 1, ui128{0});
- }
-
- Y_UNIT_TEST(Uint128Sizeof) {
- UNIT_ASSERT_EQUAL(sizeof(ui128), sizeof(ui64) * 2);
- }
-
- Y_UNIT_TEST(Uint128Cast) {
- // see util/generic/cast.h
- const auto underlyingTypeIsSelf = std::is_same<::NPrivate::TUnderlyingTypeOrSelf<ui128>, ui128>::value;
- UNIT_ASSERT_EQUAL(underlyingTypeIsSelf, true);
-
- const auto convertibleUi128Ui128 = ::NPrivate::TSafelyConvertible<ui128, ui128>::Result;
- const auto convertibleUi64Ui128 = ::NPrivate::TSafelyConvertible<ui64, ui128>::Result;
- const auto convertibleUi128Ui64 = ::NPrivate::TSafelyConvertible<ui128, ui64>::Result;
- UNIT_ASSERT_EQUAL(convertibleUi128Ui128, true); // from ui128 to ui128 => safe
- UNIT_ASSERT_EQUAL(convertibleUi64Ui128, false); // from ui128 to ui64 => not safe
- UNIT_ASSERT_EQUAL(convertibleUi128Ui64, true); // from ui64 to ui128 => safe
- }
-
- Y_UNIT_TEST(SafeIntegerCastTest) {
- ui128 narrowNumber = 1;
-
- UNIT_ASSERT_NO_EXCEPTION(SafeIntegerCast<ui64>(narrowNumber));
-
- ui128 wideNumber{0};
- wideNumber -= 1;
- UNIT_ASSERT_EXCEPTION(SafeIntegerCast<ui64>(wideNumber), yexception);
- }
-
- Y_UNIT_TEST(SignbitTest) {
- UNIT_ASSERT(!std::signbit(ui128{0}));
- UNIT_ASSERT(!std::signbit(ui128{-1}));
- UNIT_ASSERT(!std::signbit(i128{0}));
- UNIT_ASSERT(std::signbit(i128{-1}));
- }
+
+#include <util/generic/cast.h>
+
+#include <type_traits>
+
+Y_UNIT_TEST_SUITE(Uint128Suite) {
+ Y_UNIT_TEST(Uint128DefaultCtor) {
+ const ui128 value{};
+ UNIT_ASSERT_EQUAL(GetLow(value), 0);
+ UNIT_ASSERT_EQUAL(GetHigh(value), 0);
+ }
+
+ Y_UNIT_TEST(Uint128NumericLimits) {
+ UNIT_ASSERT_EQUAL(std::numeric_limits<ui128>::digits, 128);
+ UNIT_ASSERT_EQUAL(std::numeric_limits<ui128>::max() + 1, ui128{0});
+ }
+
+ Y_UNIT_TEST(Uint128Sizeof) {
+ UNIT_ASSERT_EQUAL(sizeof(ui128), sizeof(ui64) * 2);
+ }
+
+ Y_UNIT_TEST(Uint128Cast) {
+ // see util/generic/cast.h
+ const auto underlyingTypeIsSelf = std::is_same<::NPrivate::TUnderlyingTypeOrSelf<ui128>, ui128>::value;
+ UNIT_ASSERT_EQUAL(underlyingTypeIsSelf, true);
+
+ const auto convertibleUi128Ui128 = ::NPrivate::TSafelyConvertible<ui128, ui128>::Result;
+ const auto convertibleUi64Ui128 = ::NPrivate::TSafelyConvertible<ui64, ui128>::Result;
+ const auto convertibleUi128Ui64 = ::NPrivate::TSafelyConvertible<ui128, ui64>::Result;
+ UNIT_ASSERT_EQUAL(convertibleUi128Ui128, true); // from ui128 to ui128 => safe
+ UNIT_ASSERT_EQUAL(convertibleUi64Ui128, false); // from ui128 to ui64 => not safe
+ UNIT_ASSERT_EQUAL(convertibleUi128Ui64, true); // from ui64 to ui128 => safe
+ }
+
+ Y_UNIT_TEST(SafeIntegerCastTest) {
+ ui128 narrowNumber = 1;
+
+ UNIT_ASSERT_NO_EXCEPTION(SafeIntegerCast<ui64>(narrowNumber));
+
+ ui128 wideNumber{0};
+ wideNumber -= 1;
+ UNIT_ASSERT_EXCEPTION(SafeIntegerCast<ui64>(wideNumber), yexception);
+ }
+
+ Y_UNIT_TEST(SignbitTest) {
+ UNIT_ASSERT(!std::signbit(ui128{0}));
+ UNIT_ASSERT(!std::signbit(ui128{-1}));
+ UNIT_ASSERT(!std::signbit(i128{0}));
+ UNIT_ASSERT(std::signbit(i128{-1}));
+ }
Y_UNIT_TEST(ToStringTest) {
// int128
@@ -80,4 +80,4 @@ Y_UNIT_TEST_SUITE(Uint128Suite) {
),
"235108557486403940296800289353599800327");
}
-}
+}
diff --git a/library/cpp/int128/ut/int128_ut_helpers.cpp b/library/cpp/int128/ut/int128_ut_helpers.cpp
index e6c3e24d10..cb712f869a 100644
--- a/library/cpp/int128/ut/int128_ut_helpers.cpp
+++ b/library/cpp/int128/ut/int128_ut_helpers.cpp
@@ -1,56 +1,56 @@
-#include "int128_ut_helpers.h"
-
-namespace NInt128Private {
-#if defined(_little_endian_)
- std::array<ui8, 16> GetAsArray(const ui128 value) {
- std::array<ui8, 16> result;
- const ui64 low = GetLow(value);
- const ui64 high = GetHigh(value);
- MemCopy(result.data(), reinterpret_cast<const ui8*>(&low), sizeof(low));
- MemCopy(result.data() + sizeof(low), reinterpret_cast<const ui8*>(&high), sizeof(high));
- return result;
- }
-
- std::array<ui8, 16> GetAsArray(const i128 value) {
- std::array<ui8, 16> result;
- const ui64 low = GetLow(value);
- const ui64 high = GetHigh(value);
- MemCopy(result.data(), reinterpret_cast<const ui8*>(&low), sizeof(low));
- MemCopy(result.data() + sizeof(low), reinterpret_cast<const ui8*>(&high), sizeof(high));
- return result;
- }
-#elif defined(_big_endian_)
- std::array<ui8, 16> GetAsArray(const i128 value) {
- std::array<ui8, 16> result;
- const ui64 low = GetLow(value);
- const ui64 high = GetHigh(value);
- MemCopy(result.data(), reinterpret_cast<const ui8*>(&high), sizeof(high));
- MemCopy(result.data() + sizeof(high), reinterpret_cast<const ui8*>(&low), sizeof(low));
- return result;
- }
-
- std::array<ui8, 16> GetAsArray(const ui128 value) {
- std::array<ui8, 16> result;
- const ui64 low = GetLow(value);
- const ui64 high = GetHigh(value);
- MemCopy(result.data(), reinterpret_cast<const ui8*>(&high), sizeof(high));
- MemCopy(result.data() + sizeof(high), reinterpret_cast<const ui8*>(&low), sizeof(low));
- return result;
- }
-#endif
-
-#if defined(Y_HAVE_INT128)
- std::array<ui8, 16> GetAsArray(const unsigned __int128 value) {
- std::array<ui8, 16> result;
- MemCopy(result.data(), reinterpret_cast<const ui8*>(&value), sizeof(value));
- return result;
- }
-
- std::array<ui8, 16> GetAsArray(const signed __int128 value) {
- std::array<ui8, 16> result;
- MemCopy(result.data(), reinterpret_cast<const ui8*>(&value), sizeof(value));
- return result;
- }
-#endif
-
-}
+#include "int128_ut_helpers.h"
+
+namespace NInt128Private {
+#if defined(_little_endian_)
+ std::array<ui8, 16> GetAsArray(const ui128 value) {
+ std::array<ui8, 16> result;
+ const ui64 low = GetLow(value);
+ const ui64 high = GetHigh(value);
+ MemCopy(result.data(), reinterpret_cast<const ui8*>(&low), sizeof(low));
+ MemCopy(result.data() + sizeof(low), reinterpret_cast<const ui8*>(&high), sizeof(high));
+ return result;
+ }
+
+ std::array<ui8, 16> GetAsArray(const i128 value) {
+ std::array<ui8, 16> result;
+ const ui64 low = GetLow(value);
+ const ui64 high = GetHigh(value);
+ MemCopy(result.data(), reinterpret_cast<const ui8*>(&low), sizeof(low));
+ MemCopy(result.data() + sizeof(low), reinterpret_cast<const ui8*>(&high), sizeof(high));
+ return result;
+ }
+#elif defined(_big_endian_)
+ std::array<ui8, 16> GetAsArray(const i128 value) {
+ std::array<ui8, 16> result;
+ const ui64 low = GetLow(value);
+ const ui64 high = GetHigh(value);
+ MemCopy(result.data(), reinterpret_cast<const ui8*>(&high), sizeof(high));
+ MemCopy(result.data() + sizeof(high), reinterpret_cast<const ui8*>(&low), sizeof(low));
+ return result;
+ }
+
+ std::array<ui8, 16> GetAsArray(const ui128 value) {
+ std::array<ui8, 16> result;
+ const ui64 low = GetLow(value);
+ const ui64 high = GetHigh(value);
+ MemCopy(result.data(), reinterpret_cast<const ui8*>(&high), sizeof(high));
+ MemCopy(result.data() + sizeof(high), reinterpret_cast<const ui8*>(&low), sizeof(low));
+ return result;
+ }
+#endif
+
+#if defined(Y_HAVE_INT128)
+ std::array<ui8, 16> GetAsArray(const unsigned __int128 value) {
+ std::array<ui8, 16> result;
+ MemCopy(result.data(), reinterpret_cast<const ui8*>(&value), sizeof(value));
+ return result;
+ }
+
+ std::array<ui8, 16> GetAsArray(const signed __int128 value) {
+ std::array<ui8, 16> result;
+ MemCopy(result.data(), reinterpret_cast<const ui8*>(&value), sizeof(value));
+ return result;
+ }
+#endif
+
+}
diff --git a/library/cpp/int128/ut/int128_ut_helpers.h b/library/cpp/int128/ut/int128_ut_helpers.h
index b7778c3f32..99a8fa7436 100644
--- a/library/cpp/int128/ut/int128_ut_helpers.h
+++ b/library/cpp/int128/ut/int128_ut_helpers.h
@@ -1,15 +1,15 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/int128/int128.h>
-
-#include <array>
-
-namespace NInt128Private {
- std::array<ui8, 16> GetAsArray(const ui128 value);
- std::array<ui8, 16> GetAsArray(const i128 value);
-
-#if defined(Y_HAVE_INT128)
- std::array<ui8, 16> GetAsArray(const unsigned __int128 value);
- std::array<ui8, 16> GetAsArray(const signed __int128 value);
-#endif
-}
+
+#include <array>
+
+namespace NInt128Private {
+ std::array<ui8, 16> GetAsArray(const ui128 value);
+ std::array<ui8, 16> GetAsArray(const i128 value);
+
+#if defined(Y_HAVE_INT128)
+ std::array<ui8, 16> GetAsArray(const unsigned __int128 value);
+ std::array<ui8, 16> GetAsArray(const signed __int128 value);
+#endif
+}
diff --git a/library/cpp/int128/ut/int128_via_intrinsic_ut.cpp b/library/cpp/int128/ut/int128_via_intrinsic_ut.cpp
index 9decc2fd48..e1eff5fcb3 100644
--- a/library/cpp/int128/ut/int128_via_intrinsic_ut.cpp
+++ b/library/cpp/int128/ut/int128_via_intrinsic_ut.cpp
@@ -2,33 +2,33 @@
#include <library/cpp/testing/unittest/registar.h>
-// from https://a.yandex-team.ru/arc/trunk/arcadia/library/ticket_parser/c/src/ut/utils_ut.cpp?rev=4221861
+// from https://a.yandex-team.ru/arc/trunk/arcadia/library/ticket_parser/c/src/ut/utils_ut.cpp?rev=4221861
-#if defined(Y_HAVE_INT128)
-Y_UNIT_TEST_SUITE(Int128ViaIntrinsicSuite) {
+#if defined(Y_HAVE_INT128)
+Y_UNIT_TEST_SUITE(Int128ViaIntrinsicSuite) {
using guint128_t = unsigned __int128;
- guint128_t toGcc(ui128 num) {
+ guint128_t toGcc(ui128 num) {
guint128_t res = 0;
- res |= GetLow(num);
- res |= guint128_t(GetHigh(num)) << 64;
+ res |= GetLow(num);
+ res |= guint128_t(GetHigh(num)) << 64;
return res;
}
Y_UNIT_TEST(bigintTest) {
- UNIT_ASSERT(guint128_t(127) == toGcc(ui128(127)));
- UNIT_ASSERT(guint128_t(127) * guint128_t(127) == toGcc(ui128(127) * ui128(127)));
- UNIT_ASSERT(guint128_t(127) + guint128_t(127) == toGcc(ui128(127) + ui128(127)));
- UNIT_ASSERT(guint128_t(127) << 3 == toGcc(ui128(127) << 3));
- UNIT_ASSERT(guint128_t(127) >> 1 == toGcc(ui128(127) >> 1));
+ UNIT_ASSERT(guint128_t(127) == toGcc(ui128(127)));
+ UNIT_ASSERT(guint128_t(127) * guint128_t(127) == toGcc(ui128(127) * ui128(127)));
+ UNIT_ASSERT(guint128_t(127) + guint128_t(127) == toGcc(ui128(127) + ui128(127)));
+ UNIT_ASSERT(guint128_t(127) << 3 == toGcc(ui128(127) << 3));
+ UNIT_ASSERT(guint128_t(127) >> 1 == toGcc(ui128(127) >> 1));
- UNIT_ASSERT(guint128_t(1000000000027UL) * guint128_t(1000000000027UL) == toGcc(ui128(1000000000027UL) * ui128(1000000000027UL)));
- UNIT_ASSERT(guint128_t(1000000000027UL) + guint128_t(1000000000027UL) == toGcc(ui128(1000000000027UL) + ui128(1000000000027UL)));
- UNIT_ASSERT(guint128_t(1000000000027UL) << 3 == toGcc(ui128(1000000000027UL) << 3));
- UNIT_ASSERT(guint128_t(1000000000027UL) >> 1 == toGcc(ui128(1000000000027UL) >> 1));
- UNIT_ASSERT((guint128_t(1000000000027UL) * guint128_t(1000000000027UL)) << 3 == toGcc((ui128(1000000000027UL) * ui128(1000000000027UL)) << 3));
- UNIT_ASSERT((guint128_t(1000000000027UL) + guint128_t(1000000000027UL)) >> 1 == toGcc((ui128(1000000000027UL) + ui128(1000000000027UL)) >> 1));
+ UNIT_ASSERT(guint128_t(1000000000027UL) * guint128_t(1000000000027UL) == toGcc(ui128(1000000000027UL) * ui128(1000000000027UL)));
+ UNIT_ASSERT(guint128_t(1000000000027UL) + guint128_t(1000000000027UL) == toGcc(ui128(1000000000027UL) + ui128(1000000000027UL)));
+ UNIT_ASSERT(guint128_t(1000000000027UL) << 3 == toGcc(ui128(1000000000027UL) << 3));
+ UNIT_ASSERT(guint128_t(1000000000027UL) >> 1 == toGcc(ui128(1000000000027UL) >> 1));
+ UNIT_ASSERT((guint128_t(1000000000027UL) * guint128_t(1000000000027UL)) << 3 == toGcc((ui128(1000000000027UL) * ui128(1000000000027UL)) << 3));
+ UNIT_ASSERT((guint128_t(1000000000027UL) + guint128_t(1000000000027UL)) >> 1 == toGcc((ui128(1000000000027UL) + ui128(1000000000027UL)) >> 1));
- UNIT_ASSERT((ui64)(guint128_t(1000000000027UL) * guint128_t(1000000000027UL)) == GetLow(ui128(1000000000027UL) * ui128(1000000000027UL)));
+ UNIT_ASSERT((ui64)(guint128_t(1000000000027UL) * guint128_t(1000000000027UL)) == GetLow(ui128(1000000000027UL) * ui128(1000000000027UL)));
}
}
-#endif
+#endif
diff --git a/library/cpp/int128/ut/ui128_division_ut.cpp b/library/cpp/int128/ut/ui128_division_ut.cpp
index 4826a531e0..488738d429 100644
--- a/library/cpp/int128/ut/ui128_division_ut.cpp
+++ b/library/cpp/int128/ut/ui128_division_ut.cpp
@@ -1,262 +1,262 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <library/cpp/int128/int128.h>
-
-#include <util/generic/cast.h>
-
-Y_UNIT_TEST_SUITE(Ui128DivisionBy1Suite) {
- Y_UNIT_TEST(Ui128Divide0By1) {
- ui128 dividend = 0;
- ui128 divider = 1;
- ui128 expectedQuotient = 0;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide1By1) {
- ui128 dividend = 1;
- ui128 divider = 1;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide2By1) {
- ui128 dividend = 2;
- ui128 divider = 1;
- ui128 expectedQuotient = 2;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide42By1) {
- ui128 dividend = 42;
- ui128 divider = 1;
- ui128 expectedQuotient = 42;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64By1) {
- ui128 dividend = std::numeric_limits<ui64>::max();
- ui128 divider = 1;
- ui128 expectedQuotient = std::numeric_limits<ui64>::max();
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64Plus1By1) {
- ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
- ui128 divider = 1;
- ui128 expectedQuotient = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64Plus42By1) {
- ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
- ui128 divider = 1;
- ui128 expectedQuotient = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi128By1) {
- ui128 dividend = std::numeric_limits<ui128>::max();
- ui128 divider = 1;
- ui128 expectedQuotient = std::numeric_limits<ui128>::max();
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi128Minus1By1) {
- ui128 dividend = std::numeric_limits<ui128>::max() - 1;
- ui128 divider = 1;
- ui128 expectedQuotient = std::numeric_limits<ui128>::max() - 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(Ui128DivisionByEqualSuite) {
- Y_UNIT_TEST(Ui128Divide1ByEqual) {
- ui128 dividend = 1;
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide2ByEqual) {
- ui128 dividend = 2;
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide42ByEqual) {
- ui128 dividend = 42;
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64ByEqual) {
- ui128 dividend = std::numeric_limits<ui64>::max();
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64Plus1ByEqual) {
- ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64Plus42ByEqual) {
- ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi128ByEqual) {
- ui128 dividend = std::numeric_limits<ui128>::max();
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi128Minus1ByEqual) {
- ui128 dividend = std::numeric_limits<ui128>::max() - 1;
- ui128 divider = dividend;
- ui128 expectedQuotient = 1;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(Ui128DivisionLessByHigherSuite) {
- Y_UNIT_TEST(Ui128Divide42By84) {
- ui128 dividend = 42;
- ui128 divider = 84;
- ui128 expectedQuotient = 0;
- ui128 expectedRemainder = 42;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide42ByMaxUi64) {
- ui128 dividend = 42;
- ui128 divider = std::numeric_limits<ui64>::max();
- ui128 expectedQuotient = 0;
- ui128 expectedRemainder = 42;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128Divide42ByMaxUi64Plus1) {
- ui128 dividend = 42;
- ui128 divider = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
- ui128 expectedQuotient = 0;
- ui128 expectedRemainder = 42;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideMaxUi64ByMaxUi64Plus1) {
- ui128 dividend = ui128{std::numeric_limits<ui64>::max()};
- ui128 divider = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
- ui128 expectedQuotient = 0;
- ui128 expectedRemainder = ui128{std::numeric_limits<ui64>::max()};
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(Ui128DivisionBigByBigSuite) {
- Y_UNIT_TEST(Ui128DivideBigByBig1) {
- ui128 dividend = {64, 0};
- ui128 divider = {1, 0};
- ui128 expectedQuotient = 64;
- ui128 expectedRemainder = 0;
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-
- Y_UNIT_TEST(Ui128DivideBigByBig2) {
- ui128 dividend = {64, 0};
- ui128 divider = {12, 5};
- ui128 expectedQuotient = 5;
- ui128 expectedRemainder = ui128{3, 18446744073709551591ull}; // plz don't ask
-
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
-}
-
-Y_UNIT_TEST_SUITE(Ui128DivisionAlgo) {
- Y_UNIT_TEST(Ui128DivideAlgoCheck) {
- /*
- 49672666804009505000000 / 10000000 == 4967266680400950
- 49672666804009505000000 % 10000000 == 5000000
- */
- ui128 dividend = {2692ull, 14031757583392049728ull};
- ui64 divider = 10000000;
- ui128 expectedQuotient = {0, 4967266680400950ull};
- ui128 expectedRemainder = {0, 5000000ull};
-
- ui128 quotient = dividend / divider;
- ui128 reminder = dividend % divider;
-
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
-}
+
+#include <util/generic/cast.h>
+
+Y_UNIT_TEST_SUITE(Ui128DivisionBy1Suite) {
+ Y_UNIT_TEST(Ui128Divide0By1) {
+ ui128 dividend = 0;
+ ui128 divider = 1;
+ ui128 expectedQuotient = 0;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide1By1) {
+ ui128 dividend = 1;
+ ui128 divider = 1;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide2By1) {
+ ui128 dividend = 2;
+ ui128 divider = 1;
+ ui128 expectedQuotient = 2;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide42By1) {
+ ui128 dividend = 42;
+ ui128 divider = 1;
+ ui128 expectedQuotient = 42;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64By1) {
+ ui128 dividend = std::numeric_limits<ui64>::max();
+ ui128 divider = 1;
+ ui128 expectedQuotient = std::numeric_limits<ui64>::max();
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64Plus1By1) {
+ ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
+ ui128 divider = 1;
+ ui128 expectedQuotient = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64Plus42By1) {
+ ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
+ ui128 divider = 1;
+ ui128 expectedQuotient = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi128By1) {
+ ui128 dividend = std::numeric_limits<ui128>::max();
+ ui128 divider = 1;
+ ui128 expectedQuotient = std::numeric_limits<ui128>::max();
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi128Minus1By1) {
+ ui128 dividend = std::numeric_limits<ui128>::max() - 1;
+ ui128 divider = 1;
+ ui128 expectedQuotient = std::numeric_limits<ui128>::max() - 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(Ui128DivisionByEqualSuite) {
+ Y_UNIT_TEST(Ui128Divide1ByEqual) {
+ ui128 dividend = 1;
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide2ByEqual) {
+ ui128 dividend = 2;
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide42ByEqual) {
+ ui128 dividend = 42;
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64ByEqual) {
+ ui128 dividend = std::numeric_limits<ui64>::max();
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64Plus1ByEqual) {
+ ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64Plus42ByEqual) {
+ ui128 dividend = ui128{std::numeric_limits<ui64>::max()} + ui128{42};
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi128ByEqual) {
+ ui128 dividend = std::numeric_limits<ui128>::max();
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi128Minus1ByEqual) {
+ ui128 dividend = std::numeric_limits<ui128>::max() - 1;
+ ui128 divider = dividend;
+ ui128 expectedQuotient = 1;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(Ui128DivisionLessByHigherSuite) {
+ Y_UNIT_TEST(Ui128Divide42By84) {
+ ui128 dividend = 42;
+ ui128 divider = 84;
+ ui128 expectedQuotient = 0;
+ ui128 expectedRemainder = 42;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide42ByMaxUi64) {
+ ui128 dividend = 42;
+ ui128 divider = std::numeric_limits<ui64>::max();
+ ui128 expectedQuotient = 0;
+ ui128 expectedRemainder = 42;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128Divide42ByMaxUi64Plus1) {
+ ui128 dividend = 42;
+ ui128 divider = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
+ ui128 expectedQuotient = 0;
+ ui128 expectedRemainder = 42;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideMaxUi64ByMaxUi64Plus1) {
+ ui128 dividend = ui128{std::numeric_limits<ui64>::max()};
+ ui128 divider = ui128{std::numeric_limits<ui64>::max()} + ui128{1};
+ ui128 expectedQuotient = 0;
+ ui128 expectedRemainder = ui128{std::numeric_limits<ui64>::max()};
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(Ui128DivisionBigByBigSuite) {
+ Y_UNIT_TEST(Ui128DivideBigByBig1) {
+ ui128 dividend = {64, 0};
+ ui128 divider = {1, 0};
+ ui128 expectedQuotient = 64;
+ ui128 expectedRemainder = 0;
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+
+ Y_UNIT_TEST(Ui128DivideBigByBig2) {
+ ui128 dividend = {64, 0};
+ ui128 divider = {12, 5};
+ ui128 expectedQuotient = 5;
+ ui128 expectedRemainder = ui128{3, 18446744073709551591ull}; // plz don't ask
+
+ UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
+ UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
+ }
+}
+
+Y_UNIT_TEST_SUITE(Ui128DivisionAlgo) {
+ Y_UNIT_TEST(Ui128DivideAlgoCheck) {
+ /*
+ 49672666804009505000000 / 10000000 == 4967266680400950
+ 49672666804009505000000 % 10000000 == 5000000
+ */
+ ui128 dividend = {2692ull, 14031757583392049728ull};
+ ui64 divider = 10000000;
+ ui128 expectedQuotient = {0, 4967266680400950ull};
+ ui128 expectedRemainder = {0, 5000000ull};
+
+ ui128 quotient = dividend / divider;
+ ui128 reminder = dividend % divider;
+
+ UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
+ UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
+ }
+}
diff --git a/library/cpp/int128/ut/ya.make b/library/cpp/int128/ut/ya.make
index fd43531c5f..63211431bc 100644
--- a/library/cpp/int128/ut/ya.make
+++ b/library/cpp/int128/ut/ya.make
@@ -1,20 +1,20 @@
UNITTEST_FOR(library/cpp/int128)
-
-OWNER(vladon)
+
+OWNER(vladon)
SRCS(
- int128_ut_helpers.cpp
- int128_ut_helpers.h
- int128_ut.cpp
- int128_typetraits_ut.cpp
- int128_old_ut.cpp
- int128_via_intrinsic_ut.cpp
- i128_ut.cpp
- i128_and_intrinsic_identity_ut.cpp
- i128_comparison_ut.cpp
- i128_division_ut.cpp
- i128_type_traits_ut.cpp
- ui128_division_ut.cpp
+ int128_ut_helpers.cpp
+ int128_ut_helpers.h
+ int128_ut.cpp
+ int128_typetraits_ut.cpp
+ int128_old_ut.cpp
+ int128_via_intrinsic_ut.cpp
+ i128_ut.cpp
+ i128_and_intrinsic_identity_ut.cpp
+ i128_comparison_ut.cpp
+ i128_division_ut.cpp
+ i128_type_traits_ut.cpp
+ ui128_division_ut.cpp
)
END()
diff --git a/library/cpp/int128/ya.make b/library/cpp/int128/ya.make
index 95e453e6f1..ae581746c7 100644
--- a/library/cpp/int128/ya.make
+++ b/library/cpp/int128/ya.make
@@ -1,13 +1,13 @@
LIBRARY()
-OWNER(
- vladon
+OWNER(
+ vladon
# g:zora
-)
+)
SRCS(
- int128.cpp
- int128.h
+ int128.cpp
+ int128.h
)
END()