aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/int128/int128.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/int128/int128.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/int128/int128.cpp')
-rw-r--r--library/cpp/int128/int128.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/library/cpp/int128/int128.cpp b/library/cpp/int128/int128.cpp
new file mode 100644
index 0000000000..a28a389fe8
--- /dev/null
+++ b/library/cpp/int128/int128.cpp
@@ -0,0 +1,62 @@
+#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)
+{
+ if (other >= 0) {
+ out << ui128{other};
+ } else {
+ out << '-' << ui128{-other};
+ }
+ return out;
+}