Apache Ignite C++ Client
Loading...
Searching...
No Matches
big_decimal.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 "big_integer.h"
21
22#include <cassert>
23#include <cctype>
24#include <cstdint>
25#include <iostream>
26#include <sstream>
27
28namespace ignite {
29
35class big_decimal {
36public:
37 // Default
38 big_decimal() = default;
39
52 big_decimal(const std::int8_t *mag, std::int32_t len, std::int16_t scale, std::int8_t sign, bool big_endian = true)
53 : m_scale(std::int16_t(scale & 0x7FFF))
54 , m_magnitude(mag, len, sign, big_endian) {}
55
62 big_decimal(const std::byte *data, std::size_t size);
63
69 explicit big_decimal(int64_t val)
70 : m_magnitude(val) {}
71
78 big_decimal(int64_t val, int16_t scale)
79 : m_scale(scale)
80 , m_magnitude(val) {}
81
88 big_decimal(const big_integer &val, int16_t scale)
89 : m_scale(scale)
90 , m_magnitude(val) {}
91
98 big_decimal(big_integer &&val, int16_t scale)
99 : m_scale(scale)
100 , m_magnitude(std::forward<big_integer>(val)) {}
101
108 explicit big_decimal(const char *val, int32_t len)
109 : m_magnitude(0) {
110 assign_string(val, len);
111 }
112
118 explicit big_decimal(const std::string &val)
119 : m_magnitude(0) {
120 assign_string(val);
121 }
122
129 static big_decimal from_double(double val) {
130 big_decimal res;
131 res.assign_double(val);
132 return res;
133 }
134
140 [[nodiscard]] std::size_t byte_size() const noexcept;
141
148 void store_bytes(std::byte *data) const;
149
155 [[nodiscard]] std::vector<std::byte> to_bytes() const {
156 std::vector<std::byte> bytes(byte_size());
157 store_bytes(bytes.data());
158 return bytes;
159 }
160
164 explicit operator double() const { return to_double(); }
165
169 explicit operator int64_t() const { return to_int64(); }
170
176 [[nodiscard]] double to_double() const {
177 std::stringstream stream;
178 stream << *this;
179
180 double result;
181 stream >> result;
182 return result;
183 }
184
190 [[nodiscard]] int64_t to_int64() const {
191 if (m_scale == 0) {
192 return m_magnitude.to_int64();
193 }
194
195 big_decimal zero_scaled;
196
197 set_scale(0, zero_scaled);
198
199 return zero_scaled.m_magnitude.to_int64();
200 }
201
207 [[nodiscard]] std::int16_t get_scale() const noexcept { return m_scale; }
208
215 void set_scale(std::int16_t new_scale, big_decimal &res) const;
216
223 [[nodiscard]] std::int32_t get_precision() const noexcept { return m_magnitude.get_precision(); }
224
230 [[nodiscard]] const big_integer &get_unscaled_value() const noexcept { return m_magnitude; }
231
237 friend void swap(big_decimal &lhs, big_decimal &rhs) {
238 using std::swap;
239
240 swap(lhs.m_scale, rhs.m_scale);
241 swap(lhs.m_magnitude, rhs.m_magnitude);
242 }
243
249 void assign_string(const std::string &val) { assign_string(val.data(), static_cast<int32_t>(val.size())); }
250
257 void assign_string(const char *val, int32_t len) {
258 std::stringstream converter;
259
260 converter.write(val, len);
261
262 converter >> *this;
263 }
264
270 void assign_int64(int64_t val) {
271 m_magnitude.assign_int64(val);
272
273 m_scale = 0;
274 }
275
281 void assign_double(double val) {
282 std::stringstream converter;
283
284 converter.precision(16);
285
286 converter << val;
287 converter >> *this;
288 }
289
295 void assign_uint64(uint64_t val) {
296 m_magnitude.assign_uint64(val);
297
298 m_scale = 0;
299 }
300
307 void add(const big_decimal &other, big_decimal &res) const;
308
315 void subtract(const big_decimal &other, big_decimal &res) const;
316
323 void multiply(const big_decimal &other, big_decimal &res) const;
324
331 void divide(const big_decimal &other, big_decimal &res) const;
332
336 void negate() { m_magnitude.negate(); }
337
345 [[nodiscard]] int compare(const big_decimal &other) const;
346
352 [[nodiscard]] bool is_negative() const noexcept { return m_magnitude.is_negative(); }
353
359 [[nodiscard]] bool is_zero() const noexcept { return m_magnitude.is_zero(); }
360
366 [[nodiscard]] bool is_positive() const noexcept { return m_magnitude.is_positive(); }
367
375 friend std::ostream &operator<<(std::ostream &os, const big_decimal &val);
376
384 friend std::istream &operator>>(std::istream &is, big_decimal &val);
385
386private:
388 std::int16_t m_scale = 0;
389
391 big_integer m_magnitude;
392};
393
401inline bool operator==(const big_decimal &lhs, const big_decimal &rhs) noexcept {
402 return lhs.compare(rhs) == 0;
403}
404
412inline bool operator!=(const big_decimal &lhs, const big_decimal &rhs) noexcept {
413 return lhs.compare(rhs) != 0;
414}
415
423inline bool operator<(const big_decimal &lhs, const big_decimal &rhs) noexcept {
424 return lhs.compare(rhs) < 0;
425}
426
434inline bool operator<=(const big_decimal &lhs, const big_decimal &rhs) noexcept {
435 return lhs.compare(rhs) <= 0;
436}
437
445inline bool operator>(const big_decimal &lhs, const big_decimal &rhs) noexcept {
446 return lhs.compare(rhs) > 0;
447}
448
456inline bool operator>=(const big_decimal &lhs, const big_decimal &rhs) noexcept {
457 return lhs.compare(rhs) >= 0;
458}
459
467inline big_decimal operator+(const big_decimal &lhs, const big_decimal &rhs) noexcept {
468 big_decimal res;
469 lhs.add(rhs, res);
470 return res;
471}
472
480inline big_decimal operator-(const big_decimal &lhs, const big_decimal &rhs) noexcept {
481 big_decimal res;
482 lhs.subtract(rhs, res);
483 return res;
484}
485
493inline big_decimal operator*(const big_decimal &lhs, const big_decimal &rhs) noexcept {
494 big_decimal res;
495 lhs.multiply(rhs, res);
496 return res;
497}
498
506inline big_decimal operator/(const big_decimal &lhs, const big_decimal &rhs) noexcept {
507 big_decimal res;
508 lhs.divide(rhs, res);
509 return res;
510}
511
512} // namespace ignite
Definition big_decimal.h:35
std::vector< std::byte > to_bytes() const
Definition big_decimal.h:155
void add(const big_decimal &other, big_decimal &res) const
Definition big_decimal.cpp:161
big_decimal(big_integer &&val, int16_t scale)
Definition big_decimal.h:98
friend std::istream & operator>>(std::istream &is, big_decimal &val)
Definition big_decimal.cpp:112
void assign_double(double val)
Definition big_decimal.h:281
friend void swap(big_decimal &lhs, big_decimal &rhs)
Definition big_decimal.h:237
std::int32_t get_precision() const noexcept
Definition big_decimal.h:223
big_decimal(const big_integer &val, int16_t scale)
Definition big_decimal.h:88
bool is_positive() const noexcept
Definition big_decimal.h:366
double to_double() const
Definition big_decimal.h:176
void set_scale(std::int16_t new_scale, big_decimal &res) const
Definition big_decimal.cpp:43
bool is_zero() const noexcept
Definition big_decimal.h:359
big_decimal(const char *val, int32_t len)
Definition big_decimal.h:108
big_decimal(int64_t val)
Definition big_decimal.h:69
big_decimal(const std::int8_t *mag, std::int32_t len, std::int16_t scale, std::int8_t sign, bool big_endian=true)
Definition big_decimal.h:52
void assign_int64(int64_t val)
Definition big_decimal.h:270
void multiply(const big_decimal &other, big_decimal &res) const
Definition big_decimal.cpp:186
void divide(const big_decimal &other, big_decimal &res) const
Definition big_decimal.cpp:191
void assign_uint64(uint64_t val)
Definition big_decimal.h:295
big_decimal(const std::string &val)
Definition big_decimal.h:118
void assign_string(const std::string &val)
Definition big_decimal.h:249
bool is_negative() const noexcept
Definition big_decimal.h:352
std::int16_t get_scale() const noexcept
Definition big_decimal.h:207
std::size_t byte_size() const noexcept
Definition big_decimal.cpp:25
const big_integer & get_unscaled_value() const noexcept
Definition big_decimal.h:230
void negate()
Definition big_decimal.h:336
static big_decimal from_double(double val)
Definition big_decimal.h:129
big_decimal(int64_t val, int16_t scale)
Definition big_decimal.h:78
void store_bytes(std::byte *data) const
Definition big_decimal.cpp:29
int compare(const big_decimal &other) const
Definition big_decimal.cpp:64
int64_t to_int64() const
Definition big_decimal.h:190
friend std::ostream & operator<<(std::ostream &os, const big_decimal &val)
Definition big_decimal.cpp:85
void assign_string(const char *val, int32_t len)
Definition big_decimal.h:257
void subtract(const big_decimal &other, big_decimal &res) const
Definition big_decimal.cpp:174
Definition big_integer.h:37
std::int64_t to_int64() const
Definition big_integer.cpp:232