Apache Ignite C++ Client
Loading...
Searching...
No Matches
big_integer.h
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#include "bytes_view.h"
21
22#include "detail/config.h"
23#include "detail/mpi.h"
24
25#include <cstddef>
26#include <cstdint>
27#include <iostream>
28#include <vector>
29
30namespace ignite {
31
38 friend class big_decimal;
39
40 using mpi_t = detail::mpi;
41 using word_t = mpi_t::word;
42
43public:
44 // Magnitude array type.
45 using mag_array_view = mpi_t::mag_view;
46
50 big_integer() = default;
51
57 big_integer(const big_integer &other) = default;
58
64 big_integer(big_integer &&other) noexcept = default;
65
71 explicit big_integer(std::int64_t val) { assign_int64(val); }
72
78 explicit big_integer(const std::string &val) { assign_string(val); }
79
86 big_integer(const char *val, std::int32_t len) { assign_string(val, len); }
87
97 big_integer(const std::int8_t *val, std::int32_t len, std::int8_t sign, bool big_endian = true);
98
105 big_integer(const std::byte *data, std::size_t size);
106
113 big_integer &operator=(const big_integer &other) = default;
114
121 big_integer &operator=(big_integer &&other) noexcept = default;
122
129 big_integer &operator=(const mpi_t &other) {
130 if (&other == &this->m_mpi) {
131 return *this;
132 }
133
134 m_mpi = other;
135
136 return *this;
137 }
138
145 big_integer &operator=(mpi_t &&other) noexcept {
146 using std::swap;
147
148 if (&other == &this->m_mpi) {
149 return *this;
150 }
151
152 swap(m_mpi, other);
153
154 return *this;
155 }
156
162 void assign_int64(std::int64_t val);
163
169 void assign_uint64(std::uint64_t val);
170
176 void assign_string(const std::string &val);
177
184 void assign_string(const char *val, std::size_t len);
185
191 [[nodiscard]] std::int8_t get_sign() const noexcept { return std::int8_t(m_mpi.sign()); }
192
198 [[nodiscard]] mag_array_view get_magnitude() const noexcept { return m_mpi.magnitude(); }
199
205 [[nodiscard]] std::uint32_t bit_length() const noexcept;
206
212 [[nodiscard]] std::size_t byte_size() const noexcept;
213
220 void store_bytes(std::byte *data) const;
221
227 [[nodiscard]] std::vector<std::byte> to_bytes() const {
228 std::vector<std::byte> bytes(byte_size());
229 store_bytes(bytes.data());
230 return bytes;
231 }
232
239 [[nodiscard]] std::int32_t get_precision() const noexcept;
240
246 void pow(std::int32_t exp);
247
254 void multiply(const big_integer &other, big_integer &res) const;
255
262 void divide(const big_integer &divisor, big_integer &res) const;
263
271 void divide(const big_integer &divisor, big_integer &res, big_integer &rem) const;
272
279 void add(const big_integer &other, big_integer &res) const;
280
287 void subtract(const big_integer &other, big_integer &res) const;
288
294 void add(std::uint64_t x);
295
304 [[nodiscard]] int compare(const big_integer &other, bool ignore_sign = false) const;
305
311 [[nodiscard]] std::int64_t to_int64() const;
312
318 [[nodiscard]] bool is_negative() const noexcept { return m_mpi.is_negative(); }
319
325 [[nodiscard]] bool is_zero() const noexcept { return m_mpi.is_zero(); }
326
332 [[nodiscard]] bool is_positive() const noexcept { return m_mpi.is_positive(); }
333
337 void negate() { m_mpi.negate(); }
338
342 [[nodiscard]] std::string to_string() const;
343
351 friend std::ostream &operator<<(std::ostream &os, const big_integer &val);
352
360 friend std::istream &operator>>(std::istream &is, big_integer &val);
361
368 static void get_power_of_ten(std::int32_t pow, big_integer &res);
369
375 friend void swap(big_integer &lhs, big_integer &rhs);
376
377private:
383 [[nodiscard]] std::uint32_t magnitude_bit_length() const noexcept;
384
393 void divide(const big_integer &divisor, big_integer &res, big_integer *rem) const;
394
403 void from_binary(const std::uint8_t *data, std::size_t size, bool negative = false);
404
408 mutable mpi_t m_mpi;
409};
410
418inline bool operator==(const big_integer &lhs, const big_integer &rhs) noexcept {
419 return lhs.compare(rhs) == 0;
420}
421
429inline bool operator!=(const big_integer &lhs, const big_integer &rhs) noexcept {
430 return lhs.compare(rhs) != 0;
431}
432
440inline bool operator<(const big_integer &lhs, const big_integer &rhs) noexcept {
441 return lhs.compare(rhs) < 0;
442}
443
451inline bool operator<=(const big_integer &lhs, const big_integer &rhs) noexcept {
452 return lhs.compare(rhs) <= 0;
453}
454
462inline bool operator>(const big_integer &lhs, const big_integer &rhs) noexcept {
463 return lhs.compare(rhs) > 0;
464}
465
473inline bool operator>=(const big_integer &lhs, const big_integer &rhs) noexcept {
474 return lhs.compare(rhs) >= 0;
475}
476
484inline big_integer operator+(const big_integer &lhs, const big_integer &rhs) noexcept {
485 big_integer res;
486 lhs.add(rhs, res);
487 return res;
488}
489
497inline big_integer operator-(const big_integer &lhs, const big_integer &rhs) noexcept {
498 big_integer res;
499 lhs.subtract(rhs, res);
500 return res;
501}
502
510inline big_integer operator*(const big_integer &lhs, const big_integer &rhs) noexcept {
511 big_integer res;
512 lhs.multiply(rhs, res);
513 return res;
514}
515
523inline big_integer operator/(const big_integer &lhs, const big_integer &rhs) noexcept {
524 big_integer res;
525 lhs.divide(rhs, res);
526 return res;
527}
528
536inline big_integer operator%(const big_integer &lhs, const big_integer &rhs) noexcept {
537 big_integer res;
538 big_integer rem;
539 lhs.divide(rhs, res, rem);
540 return rem;
541}
542
543} // namespace ignite
Definition big_integer.h:37
void assign_string(const std::string &val)
Definition big_integer.cpp:90
void assign_int64(std::int64_t val)
Definition big_integer.cpp:63
big_integer(big_integer &&other) noexcept=default
friend std::ostream & operator<<(std::ostream &os, const big_integer &val)
Definition big_integer.cpp:258
bool is_positive() const noexcept
Definition big_integer.h:332
void store_bytes(std::byte *data) const
Definition big_integer.cpp:133
void add(const big_integer &other, big_integer &res) const
Definition big_integer.cpp:196
std::int32_t get_precision() const noexcept
Definition big_integer.cpp:153
std::size_t byte_size() const noexcept
Definition big_integer.cpp:128
big_integer & operator=(const big_integer &other)=default
std::int64_t to_int64() const
Definition big_integer.cpp:232
big_integer(const char *val, std::int32_t len)
Definition big_integer.h:86
std::vector< std::byte > to_bytes() const
Definition big_integer.h:227
void pow(std::int32_t exp)
Definition big_integer.cpp:170
mag_array_view get_magnitude() const noexcept
Definition big_integer.h:198
big_integer & operator=(const mpi_t &other)
Definition big_integer.h:129
static void get_power_of_ten(std::int32_t pow, big_integer &res)
Definition big_integer.cpp:239
std::string to_string() const
Definition big_integer.cpp:254
friend std::istream & operator>>(std::istream &is, big_integer &val)
Definition big_integer.cpp:262
friend void swap(big_integer &lhs, big_integer &rhs)
Definition big_integer.cpp:287
bool is_negative() const noexcept
Definition big_integer.h:318
big_integer(const std::string &val)
Definition big_integer.h:78
big_integer(const big_integer &other)=default
big_integer & operator=(mpi_t &&other) noexcept
Definition big_integer.h:145
std::int8_t get_sign() const noexcept
Definition big_integer.h:191
big_integer(std::int64_t val)
Definition big_integer.h:71
big_integer & operator=(big_integer &&other) noexcept=default
bool is_zero() const noexcept
Definition big_integer.h:325
void divide(const big_integer &divisor, big_integer &res) const
Definition big_integer.cpp:188
big_integer(const std::int8_t *val, std::int32_t len, std::int8_t sign, bool big_endian=true)
void multiply(const big_integer &other, big_integer &res) const
Definition big_integer.cpp:184
std::uint32_t bit_length() const noexcept
Definition big_integer.cpp:102
void subtract(const big_integer &other, big_integer &res) const
Definition big_integer.cpp:200
void assign_uint64(std::uint64_t val)
Definition big_integer.cpp:72
void negate()
Definition big_integer.h:337
int compare(const big_integer &other, bool ignore_sign=false) const
Definition big_integer.cpp:228