File indexing completed on 2025-08-28 08:27:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #pragma once
0019
0020 #include <array>
0021 #include <climits>
0022 #include <cstdint>
0023 #include <cstring>
0024 #include <limits>
0025 #include <string>
0026 #include <type_traits>
0027
0028 #include "arrow/util/endian.h"
0029 #include "arrow/util/macros.h"
0030 #include "arrow/util/type_traits.h"
0031 #include "arrow/util/visibility.h"
0032
0033 namespace arrow {
0034
0035 enum class DecimalStatus {
0036 kSuccess,
0037 kDivideByZero,
0038 kOverflow,
0039 kRescaleDataLoss,
0040 };
0041
0042 template <typename Derived, int BIT_WIDTH, int NWORDS = BIT_WIDTH / 64>
0043 class GenericBasicDecimal {
0044 protected:
0045 struct LittleEndianArrayTag {};
0046
0047 #if ARROW_LITTLE_ENDIAN
0048 static constexpr int kHighWordIndex = NWORDS - 1;
0049 static constexpr int kLowWordIndex = 0;
0050 #else
0051 static constexpr int kHighWordIndex = 0;
0052 static constexpr int kLowWordIndex = NWORDS - 1;
0053 #endif
0054
0055 public:
0056 static constexpr int kBitWidth = BIT_WIDTH;
0057 static constexpr int kByteWidth = kBitWidth / 8;
0058 static constexpr int kNumWords = NWORDS;
0059
0060
0061 static constexpr LittleEndianArrayTag LittleEndianArray{};
0062
0063 using WordArray = std::array<uint64_t, NWORDS>;
0064
0065
0066 constexpr GenericBasicDecimal() noexcept : array_({0}) {}
0067
0068
0069
0070
0071 explicit constexpr GenericBasicDecimal(const WordArray& array) noexcept
0072 : array_(array) {}
0073
0074
0075
0076
0077 GenericBasicDecimal(LittleEndianArrayTag, const WordArray& array) noexcept
0078 : GenericBasicDecimal(bit_util::little_endian::ToNative(array)) {}
0079
0080
0081 template <typename T,
0082 typename = typename std::enable_if<
0083 std::is_integral<T>::value && (sizeof(T) <= sizeof(uint64_t)), T>::type>
0084 constexpr GenericBasicDecimal(T value) noexcept
0085 : array_(WordsFromLowBits(value)) {}
0086
0087
0088
0089
0090 explicit GenericBasicDecimal(const uint8_t* bytes) {
0091 memcpy(array_.data(), bytes, sizeof(array_));
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101 constexpr const WordArray& native_endian_array() const { return array_; }
0102
0103
0104
0105
0106
0107
0108 WordArray little_endian_array() const {
0109 return bit_util::little_endian::FromNative(array_);
0110 }
0111
0112 const uint8_t* native_endian_bytes() const {
0113 return reinterpret_cast<const uint8_t*>(array_.data());
0114 }
0115
0116 uint8_t* mutable_native_endian_bytes() {
0117 return reinterpret_cast<uint8_t*>(array_.data());
0118 }
0119
0120
0121 std::array<uint8_t, kByteWidth> ToBytes() const {
0122 std::array<uint8_t, kByteWidth> out{{0}};
0123 memcpy(out.data(), array_.data(), kByteWidth);
0124 return out;
0125 }
0126
0127
0128 void ToBytes(uint8_t* out) const { memcpy(out, array_.data(), kByteWidth); }
0129
0130
0131 int64_t Sign() const {
0132 return 1 | (static_cast<int64_t>(array_[kHighWordIndex]) >> 63);
0133 }
0134
0135 bool IsNegative() const { return static_cast<int64_t>(array_[kHighWordIndex]) < 0; }
0136
0137 explicit operator bool() const { return array_ != WordArray{}; }
0138
0139 friend bool operator==(const GenericBasicDecimal& left,
0140 const GenericBasicDecimal& right) {
0141 return left.array_ == right.array_;
0142 }
0143
0144 friend bool operator!=(const GenericBasicDecimal& left,
0145 const GenericBasicDecimal& right) {
0146 return left.array_ != right.array_;
0147 }
0148
0149 protected:
0150 WordArray array_;
0151
0152 template <typename T>
0153 static constexpr uint64_t SignExtend(T low_bits) noexcept {
0154 return low_bits >= T{} ? uint64_t{0} : ~uint64_t{0};
0155 }
0156
0157 template <typename T>
0158 static constexpr WordArray WordsFromLowBits(T low_bits) {
0159 WordArray words{};
0160 if (low_bits < T{}) {
0161 for (auto& word : words) {
0162 word = ~uint64_t{0};
0163 }
0164 }
0165 words[kLowWordIndex] = static_cast<uint64_t>(low_bits);
0166 return words;
0167 }
0168 };
0169
0170 template <typename DigitType>
0171 class ARROW_EXPORT SmallBasicDecimal {
0172 public:
0173 static_assert(
0174 std::is_same_v<DigitType, int32_t> || std::is_same_v<DigitType, int64_t>,
0175 "for bitwidths larger than 64 bits use BasicDecimal128 and BasicDecimal256");
0176
0177 static constexpr int kMaxPrecision = std::numeric_limits<DigitType>::digits10;
0178 static constexpr int kMaxScale = kMaxPrecision;
0179 static constexpr int kBitWidth = sizeof(DigitType) * CHAR_BIT;
0180 static constexpr int kByteWidth = sizeof(DigitType);
0181
0182 using WordArray = std::array<std::make_unsigned_t<DigitType>, 1>;
0183
0184
0185 constexpr SmallBasicDecimal() noexcept : value_(0) {}
0186
0187
0188 template <typename T,
0189 typename = typename std::enable_if<
0190 std::is_integral<T>::value && (sizeof(T) <= sizeof(int64_t)), T>::type>
0191 constexpr SmallBasicDecimal(T value) noexcept
0192 : value_(static_cast<DigitType>(value)) {}
0193
0194
0195
0196
0197 explicit SmallBasicDecimal(const uint8_t* bytes) {
0198 memcpy(&value_, bytes, sizeof(value_));
0199 }
0200
0201 constexpr const WordArray native_endian_array() const {
0202 return WordArray{static_cast<typename WordArray::value_type>(value_)};
0203 }
0204
0205 constexpr const WordArray little_endian_array() const {
0206 return bit_util::little_endian::FromNative(
0207 WordArray{static_cast<typename WordArray::value_type>(value_)});
0208 }
0209
0210 const uint8_t* native_endian_bytes() const {
0211 return reinterpret_cast<const uint8_t*>(&value_);
0212 }
0213
0214 uint8_t* mutable_native_endian_bytes() { return reinterpret_cast<uint8_t*>(&value_); }
0215
0216
0217 std::array<uint8_t, kByteWidth> ToBytes() const {
0218 std::array<uint8_t, kByteWidth> out{{0}};
0219 memcpy(out.data(), &value_, kByteWidth);
0220 return out;
0221 }
0222
0223
0224 void ToBytes(uint8_t* out) const { memcpy(out, &value_, kByteWidth); }
0225
0226
0227 int64_t Sign() const { return 1 | (value_ >> (kBitWidth - 1)); }
0228
0229 bool IsNegative() const { return value_ < 0; }
0230
0231 explicit operator bool() const { return value_ != 0; }
0232
0233 friend bool operator==(const SmallBasicDecimal& left, const SmallBasicDecimal& right) {
0234 return left.value_ == right.value_;
0235 }
0236
0237 friend bool operator!=(const SmallBasicDecimal& left, const SmallBasicDecimal& right) {
0238 return left.value_ != right.value_;
0239 }
0240
0241 DigitType value() const { return value_; }
0242
0243
0244 int32_t CountLeadingBinaryZeros() const;
0245
0246 constexpr uint64_t low_bits() const { return static_cast<uint64_t>(value_); }
0247
0248 protected:
0249 DigitType value_;
0250 };
0251
0252 class BasicDecimal32;
0253 class BasicDecimal64;
0254
0255 ARROW_EXPORT bool operator<(const BasicDecimal32& left, const BasicDecimal32& right);
0256 ARROW_EXPORT bool operator<=(const BasicDecimal32& left, const BasicDecimal32& right);
0257 ARROW_EXPORT bool operator>(const BasicDecimal32& left, const BasicDecimal32& right);
0258 ARROW_EXPORT bool operator>=(const BasicDecimal32& left, const BasicDecimal32& right);
0259
0260 ARROW_EXPORT BasicDecimal32 operator-(const BasicDecimal32& self);
0261 ARROW_EXPORT BasicDecimal32 operator~(const BasicDecimal32& self);
0262 ARROW_EXPORT BasicDecimal32 operator+(const BasicDecimal32& left,
0263 const BasicDecimal32& right);
0264 ARROW_EXPORT BasicDecimal32 operator-(const BasicDecimal32& left,
0265 const BasicDecimal32& right);
0266 ARROW_EXPORT BasicDecimal32 operator*(const BasicDecimal32& left,
0267 const BasicDecimal32& right);
0268 ARROW_EXPORT BasicDecimal32 operator/(const BasicDecimal32& left,
0269 const BasicDecimal32& right);
0270 ARROW_EXPORT BasicDecimal32 operator%(const BasicDecimal32& left,
0271 const BasicDecimal32& right);
0272
0273 class ARROW_EXPORT BasicDecimal32 : public SmallBasicDecimal<int32_t> {
0274 public:
0275 using SmallBasicDecimal<int32_t>::SmallBasicDecimal;
0276 using ValueType = int32_t;
0277
0278
0279 BasicDecimal32& Negate();
0280
0281
0282 BasicDecimal32& Abs() { return *this < 0 ? Negate() : *this; }
0283
0284
0285 static BasicDecimal32 Abs(const BasicDecimal32& in) {
0286 BasicDecimal32 result(in);
0287 return result.Abs();
0288 }
0289
0290
0291 BasicDecimal32& operator+=(const BasicDecimal32& right) {
0292 value_ += right.value_;
0293 return *this;
0294 }
0295
0296
0297 BasicDecimal32& operator-=(const BasicDecimal32& right) {
0298 value_ -= right.value_;
0299 return *this;
0300 }
0301
0302
0303 BasicDecimal32& operator*=(const BasicDecimal32& right) {
0304 value_ *= static_cast<uint64_t>(right.value_);
0305 return *this;
0306 }
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 DecimalStatus Divide(const BasicDecimal32& divisor, BasicDecimal32* result,
0320 BasicDecimal32* remainder) const;
0321
0322
0323 BasicDecimal32& operator/=(const BasicDecimal32& right) {
0324 value_ /= right.value_;
0325 return *this;
0326 }
0327
0328
0329 BasicDecimal32& operator|=(const BasicDecimal32& right) {
0330 value_ |= right.value_;
0331 return *this;
0332 }
0333
0334
0335 BasicDecimal32& operator&=(const BasicDecimal32& right) {
0336 value_ &= right.value_;
0337 return *this;
0338 }
0339
0340 BasicDecimal32& operator<<=(uint32_t bits);
0341
0342 BasicDecimal32 operator<<(uint32_t bits) const {
0343 auto res = *this;
0344 res <<= bits;
0345 return res;
0346 }
0347
0348
0349
0350
0351 BasicDecimal32& operator>>=(uint32_t bits);
0352
0353 BasicDecimal32 operator>>(uint32_t bits) const {
0354 auto res = *this;
0355 res >>= bits;
0356 return res;
0357 }
0358
0359
0360 DecimalStatus Rescale(int32_t original_scale, int32_t new_scale,
0361 BasicDecimal32* out) const;
0362
0363 void GetWholeAndFraction(int scale, BasicDecimal32* whole,
0364 BasicDecimal32* fraction) const;
0365
0366
0367 BasicDecimal32 IncreaseScaleBy(int32_t increase_by) const;
0368
0369
0370
0371
0372
0373
0374
0375 BasicDecimal32 ReduceScaleBy(int32_t reduce_by, bool round = true) const;
0376
0377
0378
0379
0380 bool FitsInPrecision(int32_t precision) const;
0381
0382
0383 static const BasicDecimal32& GetMaxValue();
0384
0385 static BasicDecimal32 GetMaxValue(int32_t precision);
0386
0387
0388 static constexpr BasicDecimal32 GetMaxSentinel() {
0389 return BasicDecimal32(std::numeric_limits<int32_t>::max());
0390 }
0391
0392
0393 static constexpr BasicDecimal32 GetMinSentinel() {
0394 return BasicDecimal32(std::numeric_limits<int32_t>::min());
0395 }
0396
0397
0398 static const BasicDecimal32& GetScaleMultiplier(int32_t scale);
0399
0400 static const BasicDecimal32& GetHalfScaleMultiplier(int32_t scale);
0401
0402 explicit operator BasicDecimal64() const;
0403 };
0404
0405 ARROW_EXPORT bool operator<(const BasicDecimal64& left, const BasicDecimal64& right);
0406 ARROW_EXPORT bool operator<=(const BasicDecimal64& left, const BasicDecimal64& right);
0407 ARROW_EXPORT bool operator>(const BasicDecimal64& left, const BasicDecimal64& right);
0408 ARROW_EXPORT bool operator>=(const BasicDecimal64& left, const BasicDecimal64& right);
0409
0410 ARROW_EXPORT BasicDecimal64 operator-(const BasicDecimal64& self);
0411 ARROW_EXPORT BasicDecimal64 operator~(const BasicDecimal64& self);
0412 ARROW_EXPORT BasicDecimal64 operator+(const BasicDecimal64& left,
0413 const BasicDecimal64& right);
0414 ARROW_EXPORT BasicDecimal64 operator-(const BasicDecimal64& left,
0415 const BasicDecimal64& right);
0416 ARROW_EXPORT BasicDecimal64 operator*(const BasicDecimal64& left,
0417 const BasicDecimal64& right);
0418 ARROW_EXPORT BasicDecimal64 operator/(const BasicDecimal64& left,
0419 const BasicDecimal64& right);
0420 ARROW_EXPORT BasicDecimal64 operator%(const BasicDecimal64& left,
0421 const BasicDecimal64& right);
0422
0423 class ARROW_EXPORT BasicDecimal64 : public SmallBasicDecimal<int64_t> {
0424 public:
0425 using SmallBasicDecimal<int64_t>::SmallBasicDecimal;
0426 using ValueType = int64_t;
0427
0428
0429 BasicDecimal64& Negate();
0430
0431
0432 BasicDecimal64& Abs() { return *this < 0 ? Negate() : *this; }
0433
0434
0435 static BasicDecimal64 Abs(const BasicDecimal64& in) {
0436 BasicDecimal64 result(in);
0437 return result.Abs();
0438 }
0439
0440
0441 BasicDecimal64& operator+=(const BasicDecimal64& right) {
0442 value_ += right.value_;
0443 return *this;
0444 }
0445
0446
0447 BasicDecimal64& operator-=(const BasicDecimal64& right) {
0448 value_ -= right.value_;
0449 return *this;
0450 }
0451
0452
0453 BasicDecimal64& operator*=(const BasicDecimal64& right) {
0454 value_ *= static_cast<uint64_t>(right.value_);
0455 return *this;
0456 }
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 DecimalStatus Divide(const BasicDecimal64& divisor, BasicDecimal64* result,
0470 BasicDecimal64* remainder) const;
0471
0472
0473 BasicDecimal64& operator/=(const BasicDecimal64& right) {
0474 value_ /= right.value_;
0475 return *this;
0476 }
0477
0478
0479 BasicDecimal64& operator|=(const BasicDecimal64& right) {
0480 value_ |= right.value_;
0481 return *this;
0482 }
0483
0484
0485 BasicDecimal64& operator&=(const BasicDecimal64& right) {
0486 value_ &= right.value_;
0487 return *this;
0488 }
0489
0490
0491 BasicDecimal64& operator<<=(uint32_t bits);
0492
0493 BasicDecimal64 operator<<(uint32_t bits) const {
0494 auto res = *this;
0495 res <<= bits;
0496 return res;
0497 }
0498
0499
0500
0501
0502 BasicDecimal64& operator>>=(uint32_t bits);
0503
0504 BasicDecimal64 operator>>(uint32_t bits) const {
0505 auto res = *this;
0506 res >>= bits;
0507 return res;
0508 }
0509
0510
0511 DecimalStatus Rescale(int32_t original_scale, int32_t new_scale,
0512 BasicDecimal64* out) const;
0513
0514 void GetWholeAndFraction(int scale, BasicDecimal64* whole,
0515 BasicDecimal64* fraction) const;
0516
0517
0518 BasicDecimal64 IncreaseScaleBy(int32_t increase_by) const;
0519
0520
0521
0522
0523
0524
0525
0526 BasicDecimal64 ReduceScaleBy(int32_t reduce_by, bool round = true) const;
0527
0528
0529
0530
0531 bool FitsInPrecision(int32_t precision) const;
0532
0533
0534 static const BasicDecimal64& GetMaxValue();
0535
0536 static BasicDecimal64 GetMaxValue(int32_t precision);
0537
0538
0539 static constexpr BasicDecimal64 GetMaxSentinel() {
0540 return BasicDecimal64(std::numeric_limits<int32_t>::max());
0541 }
0542
0543
0544 static constexpr BasicDecimal64 GetMinSentinel() {
0545 return BasicDecimal64(std::numeric_limits<int32_t>::min());
0546 }
0547
0548
0549 static const BasicDecimal64& GetScaleMultiplier(int32_t scale);
0550
0551 static const BasicDecimal64& GetHalfScaleMultiplier(int32_t scale);
0552 };
0553
0554
0555
0556
0557
0558 class ARROW_EXPORT BasicDecimal128 : public GenericBasicDecimal<BasicDecimal128, 128> {
0559 public:
0560 static constexpr int kMaxPrecision = 38;
0561 static constexpr int kMaxScale = 38;
0562
0563 using GenericBasicDecimal::GenericBasicDecimal;
0564
0565 constexpr BasicDecimal128() noexcept : GenericBasicDecimal() {}
0566
0567
0568 #if ARROW_LITTLE_ENDIAN
0569 constexpr BasicDecimal128(int64_t high, uint64_t low) noexcept
0570 : BasicDecimal128(WordArray{low, static_cast<uint64_t>(high)}) {}
0571 #else
0572 constexpr BasicDecimal128(int64_t high, uint64_t low) noexcept
0573 : BasicDecimal128(WordArray{static_cast<uint64_t>(high), low}) {}
0574 #endif
0575
0576
0577 BasicDecimal128& Negate();
0578
0579
0580 BasicDecimal128& Abs();
0581
0582
0583 static BasicDecimal128 Abs(const BasicDecimal128& left);
0584
0585
0586 BasicDecimal128& operator+=(const BasicDecimal128& right);
0587
0588
0589 BasicDecimal128& operator-=(const BasicDecimal128& right);
0590
0591
0592 BasicDecimal128& operator*=(const BasicDecimal128& right);
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 DecimalStatus Divide(const BasicDecimal128& divisor, BasicDecimal128* result,
0606 BasicDecimal128* remainder) const;
0607
0608
0609 BasicDecimal128& operator/=(const BasicDecimal128& right);
0610
0611
0612 BasicDecimal128& operator|=(const BasicDecimal128& right);
0613
0614
0615 BasicDecimal128& operator&=(const BasicDecimal128& right);
0616
0617
0618 BasicDecimal128& operator<<=(uint32_t bits);
0619
0620 BasicDecimal128 operator<<(uint32_t bits) const {
0621 auto res = *this;
0622 res <<= bits;
0623 return res;
0624 }
0625
0626
0627
0628
0629 BasicDecimal128& operator>>=(uint32_t bits);
0630
0631 BasicDecimal128 operator>>(uint32_t bits) const {
0632 auto res = *this;
0633 res >>= bits;
0634 return res;
0635 }
0636
0637
0638 constexpr int64_t high_bits() const {
0639 #if ARROW_LITTLE_ENDIAN
0640 return static_cast<int64_t>(array_[1]);
0641 #else
0642 return static_cast<int64_t>(array_[0]);
0643 #endif
0644 }
0645
0646
0647 constexpr uint64_t low_bits() const {
0648 #if ARROW_LITTLE_ENDIAN
0649 return array_[0];
0650 #else
0651 return array_[1];
0652 #endif
0653 }
0654
0655
0656 void GetWholeAndFraction(int32_t scale, BasicDecimal128* whole,
0657 BasicDecimal128* fraction) const;
0658
0659
0660 static const BasicDecimal128& GetScaleMultiplier(int32_t scale);
0661
0662 static const BasicDecimal128& GetHalfScaleMultiplier(int32_t scale);
0663
0664
0665 DecimalStatus Rescale(int32_t original_scale, int32_t new_scale,
0666 BasicDecimal128* out) const;
0667
0668
0669 BasicDecimal128 IncreaseScaleBy(int32_t increase_by) const;
0670
0671
0672
0673
0674
0675
0676 BasicDecimal128 ReduceScaleBy(int32_t reduce_by, bool round = true) const;
0677
0678
0679
0680
0681 bool FitsInPrecision(int32_t precision) const;
0682
0683
0684 int32_t CountLeadingBinaryZeros() const;
0685
0686
0687 static const BasicDecimal128& GetMaxValue();
0688
0689
0690 static BasicDecimal128 GetMaxValue(int32_t precision);
0691
0692
0693 static constexpr BasicDecimal128 GetMaxSentinel() {
0694 return BasicDecimal128(std::numeric_limits<int64_t>::max(),
0695 std::numeric_limits<uint64_t>::max());
0696 }
0697
0698 static constexpr BasicDecimal128 GetMinSentinel() {
0699 return BasicDecimal128(std::numeric_limits<int64_t>::min(),
0700 std::numeric_limits<uint64_t>::min());
0701 }
0702 };
0703
0704 ARROW_EXPORT bool operator<(const BasicDecimal128& left, const BasicDecimal128& right);
0705 ARROW_EXPORT bool operator<=(const BasicDecimal128& left, const BasicDecimal128& right);
0706 ARROW_EXPORT bool operator>(const BasicDecimal128& left, const BasicDecimal128& right);
0707 ARROW_EXPORT bool operator>=(const BasicDecimal128& left, const BasicDecimal128& right);
0708
0709 ARROW_EXPORT BasicDecimal128 operator-(const BasicDecimal128& operand);
0710 ARROW_EXPORT BasicDecimal128 operator~(const BasicDecimal128& operand);
0711 ARROW_EXPORT BasicDecimal128 operator+(const BasicDecimal128& left,
0712 const BasicDecimal128& right);
0713 ARROW_EXPORT BasicDecimal128 operator-(const BasicDecimal128& left,
0714 const BasicDecimal128& right);
0715 ARROW_EXPORT BasicDecimal128 operator*(const BasicDecimal128& left,
0716 const BasicDecimal128& right);
0717 ARROW_EXPORT BasicDecimal128 operator/(const BasicDecimal128& left,
0718 const BasicDecimal128& right);
0719 ARROW_EXPORT BasicDecimal128 operator%(const BasicDecimal128& left,
0720 const BasicDecimal128& right);
0721
0722 class ARROW_EXPORT BasicDecimal256 : public GenericBasicDecimal<BasicDecimal256, 256> {
0723 public:
0724 using GenericBasicDecimal::GenericBasicDecimal;
0725
0726 static constexpr int kMaxPrecision = 76;
0727 static constexpr int kMaxScale = 76;
0728
0729 constexpr BasicDecimal256() noexcept : GenericBasicDecimal() {}
0730
0731 explicit BasicDecimal256(const BasicDecimal128& value) noexcept
0732 : BasicDecimal256(bit_util::little_endian::ToNative<uint64_t, 4>(
0733 {value.low_bits(), static_cast<uint64_t>(value.high_bits()),
0734 SignExtend(value.high_bits()), SignExtend(value.high_bits())})) {}
0735
0736 explicit BasicDecimal256(const BasicDecimal64& value) noexcept
0737 : BasicDecimal256(bit_util::little_endian::ToNative<uint64_t, 4>(
0738 {value.low_bits(), SignExtend(value.value()), SignExtend(value.value()),
0739 SignExtend(value.value())})) {}
0740
0741 explicit BasicDecimal256(const BasicDecimal32& value) noexcept
0742 : BasicDecimal256(bit_util::little_endian::ToNative<uint64_t, 4>(
0743 {value.low_bits(), SignExtend(value.value()), SignExtend(value.value()),
0744 SignExtend(value.value())})) {}
0745
0746
0747 BasicDecimal256& Negate();
0748
0749
0750 BasicDecimal256& Abs();
0751
0752
0753 static BasicDecimal256 Abs(const BasicDecimal256& left);
0754
0755
0756 BasicDecimal256& operator+=(const BasicDecimal256& right);
0757
0758
0759 BasicDecimal256& operator-=(const BasicDecimal256& right);
0760
0761
0762 uint64_t low_bits() const { return bit_util::little_endian::Make(array_)[0]; }
0763
0764
0765 void GetWholeAndFraction(int32_t scale, BasicDecimal256* whole,
0766 BasicDecimal256* fraction) const;
0767
0768
0769 static const BasicDecimal256& GetScaleMultiplier(int32_t scale);
0770
0771 static const BasicDecimal256& GetHalfScaleMultiplier(int32_t scale);
0772
0773
0774 DecimalStatus Rescale(int32_t original_scale, int32_t new_scale,
0775 BasicDecimal256* out) const;
0776
0777
0778 BasicDecimal256 IncreaseScaleBy(int32_t increase_by) const;
0779
0780
0781
0782
0783
0784
0785 BasicDecimal256 ReduceScaleBy(int32_t reduce_by, bool round = true) const;
0786
0787
0788
0789
0790 bool FitsInPrecision(int32_t precision) const;
0791
0792
0793 BasicDecimal256& operator*=(const BasicDecimal256& right);
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806 DecimalStatus Divide(const BasicDecimal256& divisor, BasicDecimal256* result,
0807 BasicDecimal256* remainder) const;
0808
0809
0810 BasicDecimal256& operator<<=(uint32_t bits);
0811
0812 BasicDecimal256 operator<<(uint32_t bits) const {
0813 auto res = *this;
0814 res <<= bits;
0815 return res;
0816 }
0817
0818
0819
0820
0821 BasicDecimal256& operator>>=(uint32_t bits);
0822
0823 BasicDecimal256 operator>>(uint32_t bits) const {
0824 auto res = *this;
0825 res >>= bits;
0826 return res;
0827 }
0828
0829
0830 BasicDecimal256& operator/=(const BasicDecimal256& right);
0831
0832
0833 static BasicDecimal256 GetMaxValue(int32_t precision);
0834
0835
0836 static constexpr BasicDecimal256 GetMaxSentinel() {
0837 #if ARROW_LITTLE_ENDIAN
0838 return BasicDecimal256({std::numeric_limits<uint64_t>::max(),
0839 std::numeric_limits<uint64_t>::max(),
0840 std::numeric_limits<uint64_t>::max(),
0841 static_cast<uint64_t>(std::numeric_limits<int64_t>::max())});
0842 #else
0843 return BasicDecimal256({static_cast<uint64_t>(std::numeric_limits<int64_t>::max()),
0844 std::numeric_limits<uint64_t>::max(),
0845 std::numeric_limits<uint64_t>::max(),
0846 std::numeric_limits<uint64_t>::max()});
0847 #endif
0848 }
0849
0850 static constexpr BasicDecimal256 GetMinSentinel() {
0851 #if ARROW_LITTLE_ENDIAN
0852 return BasicDecimal256(
0853 {0, 0, 0, static_cast<uint64_t>(std::numeric_limits<int64_t>::min())});
0854 #else
0855 return BasicDecimal256(
0856 {static_cast<uint64_t>(std::numeric_limits<int64_t>::min()), 0, 0, 0});
0857 #endif
0858 }
0859 };
0860
0861 ARROW_EXPORT bool operator<(const BasicDecimal256& left, const BasicDecimal256& right);
0862
0863 ARROW_EXPORT inline bool operator<=(const BasicDecimal256& left,
0864 const BasicDecimal256& right) {
0865 return !operator<(right, left);
0866 }
0867
0868 ARROW_EXPORT inline bool operator>(const BasicDecimal256& left,
0869 const BasicDecimal256& right) {
0870 return operator<(right, left);
0871 }
0872
0873 ARROW_EXPORT inline bool operator>=(const BasicDecimal256& left,
0874 const BasicDecimal256& right) {
0875 return !operator<(left, right);
0876 }
0877
0878 ARROW_EXPORT BasicDecimal256 operator-(const BasicDecimal256& operand);
0879 ARROW_EXPORT BasicDecimal256 operator~(const BasicDecimal256& operand);
0880 ARROW_EXPORT BasicDecimal256 operator+(const BasicDecimal256& left,
0881 const BasicDecimal256& right);
0882 ARROW_EXPORT BasicDecimal256 operator*(const BasicDecimal256& left,
0883 const BasicDecimal256& right);
0884 ARROW_EXPORT BasicDecimal256 operator/(const BasicDecimal256& left,
0885 const BasicDecimal256& right);
0886
0887 }