diff options
author | Geert Bosch <geert@mongodb.com> | 2016-05-11 00:13:54 -0400 |
---|---|---|
committer | Geert Bosch <geert@mongodb.com> | 2016-06-06 13:21:09 -0400 |
commit | 3ffb9e1ca369e3a5dee5ad4f420d9d4e9866e7af (patch) | |
tree | 224903b9e14b80a4241a3e9c27f00750e7cd4c4f /src/mongo/platform/decimal128.cpp | |
parent | 6a00e2746082e71691d27b3be0b75fe3be89fda7 (diff) | |
download | mongo-3ffb9e1ca369e3a5dee5ad4f420d9d4e9866e7af.tar.gz |
SERVER-19735: Add new Decimal128 operations needed by aggregation
Diffstat (limited to 'src/mongo/platform/decimal128.cpp')
-rw-r--r-- | src/mongo/platform/decimal128.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/mongo/platform/decimal128.cpp b/src/mongo/platform/decimal128.cpp index 77b6562a7fd..b4fb4f44906 100644 --- a/src/mongo/platform/decimal128.cpp +++ b/src/mongo/platform/decimal128.cpp @@ -28,6 +28,7 @@ #include "mongo/platform/decimal128.h" #include "mongo/platform/basic.h" +#include <algorithm> #include <cmath> #include <cstdlib> #include <iostream> @@ -576,6 +577,83 @@ Decimal128 Decimal128::divide(const Decimal128& other, return result; } +Decimal128 Decimal128::exponential(RoundingMode roundMode) const { + std::uint32_t throwAwayFlag = 0; + return exponential(&throwAwayFlag); +} + +Decimal128 Decimal128::exponential(std::uint32_t* signalingFlags, RoundingMode roundMode) const { + BID_UINT128 current = decimal128ToLibraryType(_value); + current = bid128_exp(current, roundMode, signalingFlags); + return Decimal128{libraryTypeToValue(current)}; +} + +Decimal128 Decimal128::logarithm(RoundingMode roundMode) const { + std::uint32_t throwAwayFlag = 0; + return logarithm(&throwAwayFlag); +} + +Decimal128 Decimal128::logarithm(std::uint32_t* signalingFlags, RoundingMode roundMode) const { + BID_UINT128 current = decimal128ToLibraryType(_value); + current = bid128_log(current, roundMode, signalingFlags); + return Decimal128{libraryTypeToValue(current)}; +} + +Decimal128 Decimal128::logarithm(const Decimal128& other, RoundingMode roundMode) const { + std::uint32_t throwAwayFlag = 0; + if (other.isEqual(Decimal128(2))) { + BID_UINT128 current = decimal128ToLibraryType(_value); + current = bid128_log2(current, roundMode, &throwAwayFlag); + return Decimal128{libraryTypeToValue(current)}; + } + if (other.isEqual(Decimal128(10))) { + BID_UINT128 current = decimal128ToLibraryType(_value); + current = bid128_log10(current, roundMode, &throwAwayFlag); + return Decimal128{libraryTypeToValue(current)}; + } + return logarithm(other, &throwAwayFlag); +} + +Decimal128 Decimal128::logarithm(const Decimal128& other, + std::uint32_t* signalingFlags, + RoundingMode roundMode) const { + return logarithm(signalingFlags, roundMode).divide(other); +} + +Decimal128 Decimal128::modulo(const Decimal128& other) const { + std::uint32_t throwAwayFlag = 0; + return modulo(other, &throwAwayFlag); +} + +Decimal128 Decimal128::modulo(const Decimal128& other, std::uint32_t* signalingFlags) const { + BID_UINT128 current = decimal128ToLibraryType(_value); + BID_UINT128 divisor = decimal128ToLibraryType(other.getValue()); + current = bid128_fmod(current, divisor, signalingFlags); + return Decimal128{libraryTypeToValue(current)}; +} + +Decimal128 Decimal128::power(const Decimal128& other, RoundingMode roundMode) const { + std::uint32_t throwAwayFlag = 0; + return power(other, &throwAwayFlag, roundMode); +} + +Decimal128 Decimal128::power(const Decimal128& other, + std::uint32_t* signalingFlags, + RoundingMode roundMode) const { + BID_UINT128 base = decimal128ToLibraryType(_value); + BID_UINT128 exp = decimal128ToLibraryType(other.getValue()); + + + BID_UINT128 result; + if (this->isEqual(Decimal128(10))) + result = bid128_exp10(exp, roundMode, signalingFlags); + else if (this->isEqual(Decimal128(2))) + result = bid128_exp2(exp, roundMode, signalingFlags); + else + result = bid128_pow(base, exp, roundMode, signalingFlags); + return Decimal128{libraryTypeToValue(result)}.add(kLargestNegativeExponentZero); +} + Decimal128 Decimal128::quantize(const Decimal128& other, RoundingMode roundMode) const { std::uint32_t throwAwayFlag = 0; return quantize(other, &throwAwayFlag, roundMode); @@ -592,6 +670,17 @@ Decimal128 Decimal128::quantize(const Decimal128& reference, return result; } +Decimal128 Decimal128::squareRoot(RoundingMode roundMode) const { + std::uint32_t throwAwayFlag = 0; + return exponential(&throwAwayFlag); +} + +Decimal128 Decimal128::squareRoot(std::uint32_t* signalingFlags, RoundingMode roundMode) const { + BID_UINT128 current = decimal128ToLibraryType(_value); + current = bid128_sqrt(current, roundMode, signalingFlags); + return Decimal128{libraryTypeToValue(current)}; +} + bool Decimal128::isEqual(const Decimal128& other) const { std::uint32_t throwAwayFlag = 0; BID_UINT128 current = decimal128ToLibraryType(_value); |