You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/07/07 06:01:27 UTC
[02/50] [abbrv] ignite git commit: IGNITE-2879: ODBC: Added decimal
support.
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/common/src/common/big_integer.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/common/big_integer.cpp b/modules/platforms/cpp/common/src/common/big_integer.cpp
new file mode 100644
index 0000000..475ddc6
--- /dev/null
+++ b/modules/platforms/cpp/common/src/common/big_integer.cpp
@@ -0,0 +1,830 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/ignite_error.h"
+#include "ignite/common/bits.h"
+#include "ignite/common/big_integer.h"
+
+namespace ignite
+{
+ namespace common
+ {
+ BigInteger::BigInteger() :
+ sign(1),
+ mag()
+ {
+ // No-op.
+ }
+
+ BigInteger::BigInteger(int64_t val) :
+ sign(1),
+ mag()
+ {
+ AssignInt64(val);
+ }
+
+ BigInteger::BigInteger(const char* val, int32_t len) :
+ sign(1),
+ mag()
+ {
+ AssignString(val, len);
+ }
+
+ BigInteger::BigInteger(const BigInteger& other) :
+ sign(other.sign),
+ mag(other.mag)
+ {
+ // No-op.
+ }
+
+ BigInteger::BigInteger(const int8_t* val, int32_t len, int32_t sign, bool bigEndian) :
+ sign(sign),
+ mag()
+ {
+ assert(val != 0);
+ assert(len > 0);
+ assert(sign == 1 || sign == 0 || sign == -1);
+ assert(val[0] != 0);
+
+ if (bigEndian)
+ {
+ int32_t firstNonZero = 0;
+ while (firstNonZero < len && val[firstNonZero] == 0)
+ ++firstNonZero;
+
+ int32_t intLength = (len - firstNonZero + 3) / 4;
+
+ mag.Resize(intLength);
+
+ int32_t b = len - 1;
+
+ for (int32_t i = 0; i < intLength - 1; ++i)
+ {
+ mag[i] = (val[b] & 0xFFUL)
+ | ((val[b - 1] & 0xFFUL) << 8)
+ | ((val[b - 2] & 0xFFUL) << 16)
+ | ((val[b - 3] & 0xFFUL) << 24);
+
+ b -= 4;
+ }
+
+ int32_t bytesRemaining = b - firstNonZero + 1;
+
+ assert(bytesRemaining > 0 && bytesRemaining <= 4);
+
+ switch (bytesRemaining)
+ {
+ case 4:
+ mag[intLength - 1] |= (val[b - 3] & 0xFF) << 24;
+
+ case 3:
+ mag[intLength - 1] |= (val[b - 2] & 0xFF) << 16;
+
+ case 2:
+ mag[intLength - 1] |= (val[b - 1] & 0xFF) << 8;
+
+ case 1:
+ mag[intLength - 1] |= val[b] & 0xFF;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ int32_t firstNonZero = len - 1;
+ while (firstNonZero >= 0 && val[firstNonZero] == 0)
+ --firstNonZero;
+
+ int32_t intLength = (firstNonZero + 4) / 4;
+
+ mag.Resize(intLength);
+
+ int32_t b = 0;
+
+ for (int32_t i = 0; i < intLength - 1; ++i)
+ {
+ mag[i] = (val[b] & 0xFFUL)
+ | ((val[b + 1] & 0xFFUL) << 8)
+ | ((val[b + 2] & 0xFFUL) << 16)
+ | ((val[b + 3] & 0xFFUL) << 24);
+
+ b += 4;
+ }
+
+ int32_t bytesRemaining = firstNonZero - b + 1;
+
+ assert(bytesRemaining > 0 && bytesRemaining <= 4);
+
+ switch (bytesRemaining)
+ {
+ case 4:
+ mag[intLength - 1] |= (val[b + 3] & 0xFF) << 24;
+
+ case 3:
+ mag[intLength - 1] |= (val[b + 2] & 0xFF) << 16;
+
+ case 2:
+ mag[intLength - 1] |= (val[b + 1] & 0xFF) << 8;
+
+ case 1:
+ mag[intLength - 1] |= val[b] & 0xFF;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ BigInteger::BigInteger(MagArray &mag, int8_t sign) :
+ sign(sign),
+ mag()
+ {
+ this->mag.Swap(mag);
+ }
+
+ BigInteger& BigInteger::operator=(const BigInteger& other)
+ {
+ Assign(other);
+
+ return *this;
+ }
+
+ void BigInteger::Assign(const BigInteger& val)
+ {
+ if (this != &val)
+ {
+ sign = val.sign;
+ mag = val.mag;
+ }
+ }
+
+ void BigInteger::AssignInt64(int64_t val)
+ {
+ if (val < 0)
+ {
+ AssignUint64(static_cast<uint64_t>(-val));
+
+ sign = -1;
+ }
+ else
+ AssignUint64(static_cast<uint64_t>(val));
+ }
+
+ void BigInteger::AssignString(const char* val, int32_t len)
+ {
+ std::stringstream converter;
+
+ converter.write(val, len);
+
+ converter >> *this;
+ }
+
+ void BigInteger::AssignUint64(uint64_t val)
+ {
+ sign = 1;
+
+ if (val == 0)
+ {
+ mag.Clear();
+
+ return;
+ }
+
+ uint32_t highWord = static_cast<uint32_t>(val >> 32);
+
+ if (highWord == 0)
+ mag.Resize(1);
+ else
+ {
+ mag.Resize(2);
+ mag[1] = highWord;
+ }
+
+ mag[0] = static_cast<uint32_t>(val);
+ }
+
+ int8_t BigInteger::GetSign() const
+ {
+ return sign;
+ }
+
+ void BigInteger::Swap(BigInteger& other)
+ {
+ using std::swap;
+
+ swap(sign, other.sign);
+ mag.Swap(other.mag);
+ }
+
+ const BigInteger::MagArray& BigInteger::GetMagnitude() const
+ {
+ return mag;
+ }
+
+ uint32_t BigInteger::GetBitLength() const
+ {
+ if (mag.IsEmpty())
+ return 0;
+
+ int32_t res = bits::BitLengthU32(mag[mag.GetSize() - 1]);
+
+ if (mag.GetSize() > 1)
+ res += (mag.GetSize() - 1) * 32;
+
+ return res;
+ }
+
+ int32_t BigInteger::GetPrecision() const
+ {
+ // See http://graphics.stanford.edu/~seander/bithacks.html
+ // for the details on the algorithm.
+
+ if (mag.GetSize() == 0)
+ return 1;
+
+ int32_t r = static_cast<uint32_t>(((
+ static_cast<uint64_t>(GetBitLength()) + 1) * 646456993ULL) >> 31);
+
+ BigInteger prec;
+ BigInteger::GetPowerOfTen(r, prec);
+
+ return Compare(prec, true) < 0 ? r : r + 1;
+ }
+
+ void BigInteger::MagnitudeToBytes(common::FixedSizeArray<int8_t>& buffer) const
+ {
+ int32_t bytesNum = static_cast<int32_t>((GetBitLength() + 7) / 8);
+
+ buffer.Reset(bytesNum);
+
+ int32_t i;
+ for (i = 0; i < mag.GetSize() - 1; ++i)
+ {
+ int32_t j = bytesNum - 1 - 4 * i;
+
+ buffer[j] = static_cast<int8_t>(mag[i]);
+ buffer[j - 1] = static_cast<int8_t>(mag[i] >> 8);
+ buffer[j - 2] = static_cast<int8_t>(mag[i] >> 16);
+ buffer[j - 3] = static_cast<int8_t>(mag[i] >> 24);
+ }
+
+ int32_t bytesRemaining = bytesNum - 4 * i;
+
+ assert(bytesRemaining >= 0 && bytesRemaining <= 4);
+
+ i = 0;
+ switch (bytesRemaining)
+ {
+ case 4:
+ buffer[i++] |= static_cast<int8_t>(mag[mag.GetSize() - 1] >> 24);
+
+ case 3:
+ buffer[i++] |= static_cast<int8_t>(mag[mag.GetSize() - 1] >> 16);
+
+ case 2:
+ buffer[i++] |= static_cast<int8_t>(mag[mag.GetSize() - 1] >> 8);
+
+ case 1:
+ buffer[i++] |= static_cast<int8_t>(mag[mag.GetSize() - 1]);
+
+ default:
+ break;
+ }
+ }
+
+ void BigInteger::Pow(int32_t exp)
+ {
+ if (exp < 0)
+ {
+ AssignInt64(0);
+
+ return;
+ }
+
+ uint32_t bitsLen = GetBitLength();
+
+ if (!bitsLen)
+ return;
+
+ if (bitsLen == 1)
+ {
+ if ((exp % 2 == 0) && sign < 0)
+ sign = -sign;
+
+ return;
+ }
+
+ BigInteger multiplicant(*this);
+ AssignInt64(1);
+
+ int32_t mutExp = exp;
+ while (mutExp)
+ {
+ if (mutExp & 1)
+ Multiply(multiplicant, *this);
+
+ mutExp >>= 1;
+
+ if (mutExp)
+ multiplicant.Multiply(multiplicant, multiplicant);
+ }
+ }
+
+ void BigInteger::Multiply(const BigInteger& other, BigInteger& res) const
+ {
+ MagArray resMag(mag.GetSize() + other.mag.GetSize());
+
+ resMag.Resize(mag.GetSize() + other.mag.GetSize());
+
+ for (int32_t i = 0; i < other.mag.GetSize(); ++i)
+ {
+ uint32_t carry = 0;
+
+ for (int32_t j = 0; j < mag.GetSize(); ++j)
+ {
+ uint64_t product = static_cast<uint64_t>(mag[j]) * other.mag[i] +
+ + resMag[i + j] + carry;
+
+ resMag[i + j] = static_cast<uint32_t>(product);
+ carry = static_cast<uint32_t>(product >> 32);
+ }
+
+ resMag[i + mag.GetSize()] = carry;
+ }
+
+ res.mag.Swap(resMag);
+ res.sign = sign * other.sign;
+
+ res.Normalize();
+ }
+
+ /**
+ * Shift magnitude left by the specified number of bits.
+ *
+ * @param in Input magnitude.
+ * @param len Magnitude length.
+ * @param out Output magnitude. Should be not shorter than the input
+ * magnitude.
+ * @param n Number of bits to shift to.
+ */
+ void ShiftLeft(const uint32_t* in, int32_t len, uint32_t* out, unsigned n)
+ {
+ assert(n < 32);
+
+ if (n == 0)
+ {
+ std::copy(in, in + len, out);
+
+ return;
+ }
+
+ for (int32_t i = len - 1; i > 0; --i)
+ out[i] = (in[i] << n) | (in[i - 1] >> (32 - n));
+
+ out[0] = in[0] << n;
+ }
+
+ /**
+ * Shift magnitude right by the specified number of bits.
+ *
+ * @param in Input magnitude.
+ * @param len Magnitude length.
+ * @param out Output magnitude. Should be not shorter than the input
+ * magnitude.
+ * @param n Number of bits to shift to.
+ */
+ void ShiftRight(const uint32_t* in, int32_t len, uint32_t* out, unsigned n)
+ {
+ assert(n < 32);
+
+ if (n == 0)
+ {
+ std::copy(in, in + len, out);
+
+ return;
+ }
+
+ for (int32_t i = 0; i < len - 1; ++i)
+ out[i] = (in[i] >> n) | (in[i + 1] << (32 - n));
+
+ out[len - 1] = in[len - 1] >> n;
+ }
+
+ /**
+ * Part of the division algorithm. Computes q - (a * x).
+ *
+ * @param q Minuend.
+ * @param a Multipliplier of the subtrahend.
+ * @param alen Length of the a.
+ * @param x Multipliplicand of the subtrahend.
+ * @return Carry.
+ */
+ uint32_t MultiplyAndSubstruct(uint32_t* q, const uint32_t* a, int32_t alen, uint32_t x)
+ {
+ uint64_t carry = 0;
+
+ for (int32_t i = 0; i < alen; ++i)
+ {
+ uint64_t product = a[i] * static_cast<uint64_t>(x);
+ int64_t difference = q[i] - carry - (product & 0xFFFFFFFF);
+
+ q[i] = static_cast<uint32_t>(difference);
+
+ // This will add one if difference is negative.
+ carry = (product >> 32) - (difference >> 32);
+ }
+
+ return static_cast<uint32_t>(carry);
+ }
+
+ /**
+ * Add two magnitude arrays and return carry.
+ *
+ * @param res First addend. Result is placed here. Length of this addend
+ * should be equal or greater than len.
+ * @param addend Second addend.
+ * @param len Length of the second addend.
+ * @return Carry.
+ */
+ uint32_t Add(uint32_t* res, const uint32_t* addend, int32_t len)
+ {
+ uint64_t carry = 0;
+
+ for (int32_t i = 0; i < len; ++i)
+ {
+ uint64_t sum = static_cast<uint64_t>(res[i]) + addend[i] + carry;
+ res[i] = static_cast<uint32_t>(sum);
+ carry = sum >> 32;
+ }
+
+ return static_cast<uint32_t>(carry);
+ }
+
+ /**
+ * Add single number to a magnitude array and return carry.
+ *
+ * @param res First addend. Result is placed here. Length of this addend
+ * should be equal or greater than len.
+ * @param len Length of the First addend.
+ * @param addend Second addend.
+ * @return Carry.
+ */
+ uint32_t Add(uint32_t* res, int32_t len, uint32_t addend)
+ {
+ uint64_t carry = addend;
+
+ for (int32_t i = 0; (i < len) && carry; ++i)
+ {
+ uint64_t sum = static_cast<uint64_t>(res[i]) + carry;
+ res[i] = static_cast<uint32_t>(sum);
+ carry = sum >> 32;
+ }
+
+ return static_cast<uint32_t>(carry);
+ }
+
+ void BigInteger::Divide(const BigInteger& divisor, BigInteger& res) const
+ {
+ Divide(divisor, res, 0);
+ }
+
+ void BigInteger::Divide(const BigInteger& divisor, BigInteger& res, BigInteger& rem) const
+ {
+ Divide(divisor, res, &rem);
+ }
+
+ void BigInteger::Add(const uint32_t* addend, int32_t len)
+ {
+ if (mag.GetSize() < len)
+ {
+ mag.Reserve(len + 1);
+
+ mag.Resize(len);
+ }
+ else
+ mag.Reserve(mag.GetSize() + 1);
+
+ uint32_t carry = common::Add(mag.GetData(), addend, len);
+
+ if (carry)
+ {
+ carry = common::Add(mag.GetData() + len, mag.GetSize() - len, carry);
+
+ if (carry)
+ mag.PushBack(carry);
+ }
+ }
+
+ void BigInteger::Add(uint64_t x)
+ {
+ if (x == 0)
+ return;
+
+ if (IsZero())
+ {
+ AssignUint64(x);
+
+ return;
+ }
+
+ uint32_t val[2];
+
+ val[0] = static_cast<uint32_t>(x);
+ val[1] = static_cast<uint32_t>(x >> 32);
+
+ Add(val, val[1] ? 2 : 1);
+ }
+
+ int32_t BigInteger::Compare(const BigInteger& other, bool ignoreSign) const
+ {
+ // What we should return if magnitude is greater.
+ int32_t mgt = 1;
+
+ if (!ignoreSign)
+ {
+ if (sign != other.sign)
+ return sign > other.sign ? 1 : -1;
+ else
+ mgt = sign;
+ }
+
+ if (mag.GetSize() != other.mag.GetSize())
+ return mag.GetSize() > other.mag.GetSize() ? mgt : -mgt;
+
+ for (int32_t i = mag.GetSize() - 1; i >= 0; --i)
+ {
+ if (mag[i] == other.mag[i])
+ continue;
+ else if (mag[i] > other.mag[i])
+ return mgt;
+ else
+ return -mgt;
+ }
+
+ return 0;
+ }
+
+ int64_t BigInteger::ToInt64() const
+ {
+ return (static_cast<uint64_t>(GetMagInt(1)) << 32) | GetMagInt(0);
+ }
+
+ void BigInteger::GetPowerOfTen(int32_t pow, BigInteger& res)
+ {
+ using namespace common;
+
+ assert(pow >= 0);
+
+ if (pow < bits::UINT64_MAX_PRECISION)
+ {
+ res.AssignUint64(bits::TenPowerU64(pow));
+
+ return;
+ }
+
+ res.AssignInt64(10);
+ res.Pow(pow);
+ }
+
+ uint32_t BigInteger::GetMagInt(int32_t n) const
+ {
+ assert(n >= 0);
+
+ if (n >= mag.GetSize())
+ return sign > 0 ? 0 : -1;
+
+ return sign * mag[n];
+ }
+
+ void BigInteger::Divide(const BigInteger& divisor, BigInteger& res, BigInteger* rem) const
+ {
+ // Can't divide by zero.
+ if (divisor.mag.IsEmpty())
+ throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, "Division by zero.");
+
+ int32_t compRes = Compare(divisor, true);
+
+ int8_t resSign = sign * divisor.sign;
+
+ // The same magnitude. Result is [-]1 and remainder is zero.
+ if (compRes == 0)
+ {
+ res.AssignInt64(resSign);
+
+ if (rem)
+ rem->AssignInt64(0);
+
+ return;
+ }
+
+ // Divisor is greater than this. Result is 0 and remainder is this.
+ if (compRes == -1)
+ {
+ // Order is important here! Copy to rem first to handle the case
+ // when &res == this.
+ if (rem)
+ rem->Assign(*this);
+
+ res.AssignInt64(0);
+
+ return;
+ }
+
+ // If divisor is [-]1 result is [-]this and remainder is zero.
+ if (divisor.GetBitLength() == 1)
+ {
+ // Once again: order is important.
+ res.Assign(*this);
+ res.sign = sign * divisor.sign;
+
+ if (rem)
+ rem->AssignInt64(0);
+
+ return;
+ }
+
+ // Trivial case.
+ if (mag.GetSize() <= 2)
+ {
+ uint64_t u = mag[0];
+ uint64_t v = divisor.mag[0];
+
+ if (mag.GetSize() == 2)
+ u |= static_cast<uint64_t>(mag[1]) << 32;
+
+ if (divisor.mag.GetSize() == 2)
+ v |= static_cast<uint64_t>(divisor.mag[1]) << 32;
+
+ // Divisor can not be 1, or 0.
+ assert(v > 1);
+
+ // It should also be less than dividend.
+ assert(v < u);
+
+ // (u / v) is always fits into int64_t because abs(v) >= 2.
+ res.AssignInt64(resSign * static_cast<int64_t>(u / v));
+
+ // (u % v) is always fits into int64_t because (u > v) ->
+ // (u % v) < (u / 2).
+ if (rem)
+ rem->AssignInt64(resSign * static_cast<int64_t>(u % v));
+
+ return;
+ }
+
+ // Using Knuth division algorithm D for common case.
+
+ // Short aliases.
+ const MagArray& u = mag;
+ const MagArray& v = divisor.mag;
+ MagArray& q = res.mag;
+ int32_t ulen = u.GetSize();
+ int32_t vlen = v.GetSize();
+
+ // First we need to normilize divisor.
+ MagArray nv;
+ nv.Resize(v.GetSize());
+
+ int32_t shift = bits::NumberOfLeadingZerosU32(v.Back());
+ ShiftLeft(v.GetData(), vlen, nv.GetData(), shift);
+
+ // Divisor is normilized. Now we need to normilize divident.
+ MagArray nu;
+
+ // First find out what is the size of it.
+ if (bits::NumberOfLeadingZerosU32(u.Back()) >= shift)
+ {
+ // Everything is the same as with divisor. Just add leading zero.
+ nu.Resize(ulen + 1);
+
+ ShiftLeft(u.GetData(), ulen, nu.GetData(), shift);
+
+ assert((static_cast<uint64_t>(u.Back()) >> (32 - shift)) == 0);
+ }
+ else
+ {
+ // We need one more byte here. Also adding leading zero.
+ nu.Resize(ulen + 2);
+
+ ShiftLeft(u.GetData(), ulen, nu.GetData(), shift);
+
+ nu[ulen] = u[ulen - 1] >> (32 - shift);
+
+ assert(nu[ulen] != 0);
+ }
+
+ assert(nu.Back() == 0);
+
+ // Resizing resulting array.
+ q.Resize(ulen - vlen + 1);
+
+ // Main loop
+ for (int32_t i = ulen - vlen; i >= 0; --i)
+ {
+ uint64_t base = bits::MakeU64(nu[i + vlen], nu[i + vlen - 1]);
+
+ uint64_t qhat = base / nv[vlen - 1]; // Estimated quotient.
+ uint64_t rhat = base % nv[vlen - 1]; // A remainder.
+
+ // Adjusting result if needed.
+ while (qhat > UINT32_MAX ||
+ ((qhat * nv[vlen - 2]) > ((UINT32_MAX + 1ULL) * rhat + nu[i + vlen - 2])))
+ {
+ --qhat;
+ rhat += nv[vlen - 1];
+
+ if (rhat > UINT32_MAX)
+ break;
+ }
+
+ uint32_t qhat32 = static_cast<uint32_t>(qhat);
+
+ // Multiply and subtract.
+ uint32_t carry = MultiplyAndSubstruct(nu.GetData() + i, nv.GetData(), vlen, qhat32);
+
+ int64_t difference = nu[i + vlen] - carry;
+
+ nu[i + vlen] = static_cast<uint32_t>(difference);
+
+ if (difference < 0)
+ {
+ --qhat32;
+ carry = common::Add(nu.GetData() + i, nv.GetData(), vlen);
+
+ assert(carry == 0);
+ }
+
+ q[i] = qhat32;
+ }
+
+ res.sign = resSign;
+ res.Normalize();
+
+ // If remainder is needed unnormolize it.
+ if (rem)
+ {
+ rem->sign = resSign;
+ rem->mag.Resize(vlen);
+
+ ShiftRight(nu.GetData(), rem->mag.GetSize(), rem->mag.GetData(), shift);
+
+ rem->Normalize();
+ }
+ }
+
+ void BigInteger::Normalize()
+ {
+ int32_t lastNonZero = mag.GetSize() - 1;
+ while (lastNonZero >= 0 && mag[lastNonZero] == 0)
+ --lastNonZero;
+
+ mag.Resize(lastNonZero + 1);
+ }
+
+ bool operator==(const BigInteger& val1, const BigInteger& val2)
+ {
+ return val1.Compare(val2) == 0;
+ }
+
+ bool operator!=(const BigInteger& val1, const BigInteger& val2)
+ {
+ return val1.Compare(val2) != 0;
+ }
+
+ bool operator<(const BigInteger& val1, const BigInteger& val2)
+ {
+ return val1.Compare(val2) < 0;
+ }
+
+ bool operator<=(const BigInteger& val1, const BigInteger& val2)
+ {
+ return val1.Compare(val2) <= 0;
+ }
+
+ bool operator>(const BigInteger& val1, const BigInteger& val2)
+ {
+ return val1.Compare(val2) > 0;
+ }
+
+ bool operator>=(const BigInteger& val1, const BigInteger& val2)
+ {
+ return val1.Compare(val2) >= 0;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/common/src/common/bits.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/common/bits.cpp b/modules/platforms/cpp/common/src/common/bits.cpp
new file mode 100644
index 0000000..93f2221
--- /dev/null
+++ b/modules/platforms/cpp/common/src/common/bits.cpp
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cassert>
+
+#include "ignite/common/bits.h"
+
+namespace ignite
+{
+ namespace common
+ {
+ namespace bits
+ {
+ int32_t NumberOfTrailingZerosI32(int32_t i)
+ {
+ int32_t y;
+
+ if (i == 0) return 32;
+
+ int32_t n = 31;
+
+ y = i << 16;
+
+ if (y != 0) {
+ n = n - 16;
+ i = y;
+ }
+
+ y = i << 8;
+
+ if (y != 0) {
+ n = n - 8;
+ i = y;
+ }
+
+ y = i << 4;
+
+ if (y != 0) {
+ n = n - 4;
+ i = y;
+ }
+
+ y = i << 2;
+
+ if (y != 0) {
+ n = n - 2;
+ i = y;
+ }
+
+ return n - static_cast<int32_t>(static_cast<uint32_t>(i << 1) >> 31);
+ }
+
+ int32_t NumberOfLeadingZerosI32(int32_t i)
+ {
+ return NumberOfLeadingZerosU32(static_cast<uint32_t>(i));
+ }
+
+ int32_t NumberOfLeadingZerosU32(uint32_t i)
+ {
+ if (i == 0)
+ return 32;
+
+ int32_t n = 1;
+
+ if (i >> 16 == 0) {
+ n += 16;
+ i <<= 16;
+ }
+
+ if (i >> 24 == 0) {
+ n += 8;
+ i <<= 8;
+ }
+
+ if (i >> 28 == 0) {
+ n += 4;
+ i <<= 4;
+ }
+
+ if (i >> 30 == 0) {
+ n += 2;
+ i <<= 2;
+ }
+
+ return n - static_cast<int32_t>(i >> 31);
+ }
+
+ int32_t NumberOfLeadingZerosI64(int64_t i)
+ {
+ return NumberOfLeadingZerosU64(static_cast<uint64_t>(i));
+ }
+
+ int32_t NumberOfLeadingZerosU64(uint64_t i)
+ {
+ if (i == 0)
+ return 64;
+
+ int32_t n = 1;
+
+ uint32_t x = static_cast<uint32_t>(i >> 32);
+
+ if (x == 0) {
+ n += 32;
+ x = static_cast<uint32_t>(i);
+ }
+
+ if (x >> 16 == 0) {
+ n += 16;
+ x <<= 16;
+ }
+
+ if (x >> 24 == 0) {
+ n += 8;
+ x <<= 8;
+ }
+
+ if (x >> 28 == 0) {
+ n += 4;
+ x <<= 4;
+ }
+
+ if (x >> 30 == 0) {
+ n += 2;
+ x <<= 2;
+ }
+
+ n -= x >> 31;
+
+ return n;
+ }
+
+ int32_t BitCountI32(int32_t i)
+ {
+ uint32_t ui = static_cast<uint32_t>(i);
+
+ ui -= (ui >> 1) & 0x55555555;
+ ui = (ui & 0x33333333) + ((ui >> 2) & 0x33333333);
+ ui = (ui + (ui >> 4)) & 0x0f0f0f0f;
+ ui += ui >> 8;
+ ui += ui >> 16;
+
+ return static_cast<int32_t>(ui & 0x3f);
+ }
+
+ int32_t BitLengthI32(int32_t i)
+ {
+ return 32 - NumberOfLeadingZerosI32(i);
+ }
+
+ int32_t BitLengthU32(uint32_t i)
+ {
+ return 32 - NumberOfLeadingZerosU32(i);
+ }
+
+ int32_t GetCapasityForSize(int32_t size)
+ {
+ assert(size > 0);
+
+ if (size <= 8)
+ return 8;
+
+ int32_t bl = BitLengthI32(size);
+
+ if (bl > 30)
+ return INT32_MAX;
+
+ int32_t res = 1 << bl;
+
+ return size > res ? res << 1 : res;
+ }
+
+ int32_t DigitLength(uint64_t x)
+ {
+ // See http://graphics.stanford.edu/~seander/bithacks.html
+ // for the details on the algorithm.
+
+ if (x < 10)
+ return 1;
+
+ int32_t r = ((64 - NumberOfLeadingZerosU64(x) + 1) * 1233) >> 12;
+
+ assert(r <= UINT64_MAX_PRECISION);
+
+ return (r == UINT64_MAX_PRECISION || x < TenPowerU64(r)) ? r : r + 1;
+ }
+
+ uint64_t TenPowerU64(int32_t n)
+ {
+ static const uint64_t TEN_POWERS_TABLE[UINT64_MAX_PRECISION] = {
+ 1ULL, // 0 / 10^0
+ 10ULL, // 1 / 10^1
+ 100ULL, // 2 / 10^2
+ 1000ULL, // 3 / 10^3
+ 10000ULL, // 4 / 10^4
+ 100000ULL, // 5 / 10^5
+ 1000000ULL, // 6 / 10^6
+ 10000000ULL, // 7 / 10^7
+ 100000000ULL, // 8 / 10^8
+ 1000000000ULL, // 9 / 10^9
+ 10000000000ULL, // 10 / 10^10
+ 100000000000ULL, // 11 / 10^11
+ 1000000000000ULL, // 12 / 10^12
+ 10000000000000ULL, // 13 / 10^13
+ 100000000000000ULL, // 14 / 10^14
+ 1000000000000000ULL, // 15 / 10^15
+ 10000000000000000ULL, // 16 / 10^16
+ 100000000000000000ULL, // 17 / 10^17
+ 1000000000000000000ULL, // 18 / 10^18
+ 10000000000000000000ULL // 19 / 10^19
+ };
+
+ assert(n >= 0 && n < UINT64_MAX_PRECISION);
+
+ return TEN_POWERS_TABLE[n];
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/Makefile.am b/modules/platforms/cpp/core-test/Makefile.am
index d1f4ca5..7a62e8e 100644
--- a/modules/platforms/cpp/core-test/Makefile.am
+++ b/modules/platforms/cpp/core-test/Makefile.am
@@ -47,6 +47,7 @@ ignite_tests_LDFLAGS = \
-static-libtool-libs
ignite_tests_SOURCES = \
+ src/bits_test.cpp \
src/cache_test.cpp \
src/cache_query_test.cpp \
src/concurrent_test.cpp \
@@ -58,6 +59,9 @@ ignite_tests_SOURCES = \
src/binary_reader_writer_raw_test.cpp \
src/binary_reader_writer_test.cpp \
src/binary_session_test.cpp \
+ src/decimal_test.cpp \
+ src/dynamic_size_array_test.cpp \
+ src/fixed_size_array_test.cpp \
src/transactions_test.cpp \
src/teamcity_messages.cpp \
src/teamcity_boost.cpp
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
index edf87ba..acdfee0 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
@@ -22,6 +22,9 @@
<ProjectReference Include="..\..\..\binary\project\vs\binary.vcxproj">
<Project>{4f15669b-92eb-49f0-b774-8f19bae0b960}</Project>
</ProjectReference>
+ <ProjectReference Include="..\..\..\common\project\vs\common.vcxproj">
+ <Project>{b63f2e01-5157-4719-8491-0e1c7cd3b701}</Project>
+ </ProjectReference>
<ProjectReference Include="..\..\..\core\project\vs\core.vcxproj">
<Project>{e2dea693-f2ea-43c2-a813-053378f6e4db}</Project>
</ProjectReference>
@@ -36,6 +39,9 @@
<ItemGroup>
<ClCompile Include="..\..\src\cache_test.cpp" />
<ClCompile Include="..\..\src\concurrent_test.cpp" />
+ <ClCompile Include="..\..\src\decimal_test.cpp" />
+ <ClCompile Include="..\..\src\dynamic_size_array_test.cpp" />
+ <ClCompile Include="..\..\src\fixed_size_array_test.cpp" />
<ClCompile Include="..\..\src\ignite_error_test.cpp" />
<ClCompile Include="..\..\src\ignition_test.cpp" />
<ClCompile Include="..\..\src\handle_registry_test.cpp" />
@@ -45,6 +51,7 @@
<ClCompile Include="..\..\src\binary_test_defs.cpp" />
<ClCompile Include="..\..\src\cache_query_test.cpp" />
<ClCompile Include="..\..\src\interop_memory_test.cpp" />
+ <ClCompile Include="..\..\src\bits_test.cpp" />
<ClCompile Include="..\..\src\teamcity_boost.cpp" />
<ClCompile Include="..\..\src\teamcity_messages.cpp" />
<ClCompile Include="..\..\src\transactions_test.cpp" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
index 2259f4c..0366374 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
@@ -43,6 +43,18 @@
<ClCompile Include="..\..\src\transactions_test.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\bits_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\decimal_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\fixed_size_array_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\dynamic_size_array_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\teamcity_messages.h">
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/src/bits_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/bits_test.cpp b/modules/platforms/cpp/core-test/src/bits_test.cpp
new file mode 100644
index 0000000..3aadf36
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/bits_test.cpp
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include <ignite/common/bits.h>
+
+using namespace ignite;
+using namespace ignite::common::bits;
+
+BOOST_AUTO_TEST_SUITE(BitsTestSuite)
+
+BOOST_AUTO_TEST_CASE(TestNumberOfLeadingZeroes)
+{
+ BOOST_CHECK_EQUAL(32, NumberOfLeadingZerosI32(0));
+
+ BOOST_CHECK_EQUAL(31, NumberOfLeadingZerosI32(1));
+
+ BOOST_CHECK_EQUAL(30, NumberOfLeadingZerosI32(2));
+ BOOST_CHECK_EQUAL(30, NumberOfLeadingZerosI32(3));
+
+ BOOST_CHECK_EQUAL(29, NumberOfLeadingZerosI32(4));
+ BOOST_CHECK_EQUAL(29, NumberOfLeadingZerosI32(5));
+ BOOST_CHECK_EQUAL(29, NumberOfLeadingZerosI32(7));
+
+ BOOST_CHECK_EQUAL(28, NumberOfLeadingZerosI32(8));
+ BOOST_CHECK_EQUAL(28, NumberOfLeadingZerosI32(12));
+ BOOST_CHECK_EQUAL(28, NumberOfLeadingZerosI32(15));
+
+ BOOST_CHECK_EQUAL(0, NumberOfLeadingZerosI32(0xFFFFFFFF));
+ BOOST_CHECK_EQUAL(0, NumberOfLeadingZerosI32(0x80000000));
+
+ BOOST_CHECK_EQUAL(1, NumberOfLeadingZerosI32(0x7FFFFFFF));
+ BOOST_CHECK_EQUAL(1, NumberOfLeadingZerosI32(0x40000000));
+
+ BOOST_CHECK_EQUAL(8, NumberOfLeadingZerosI32(0x00FFFFFF));
+ BOOST_CHECK_EQUAL(8, NumberOfLeadingZerosI32(0x00F00000));
+ BOOST_CHECK_EQUAL(8, NumberOfLeadingZerosI32(0x00800000));
+
+ BOOST_CHECK_EQUAL(9, NumberOfLeadingZerosI32(0x00700000));
+ BOOST_CHECK_EQUAL(9, NumberOfLeadingZerosI32(0x00400000));
+ BOOST_CHECK_EQUAL(9, NumberOfLeadingZerosI32(0x006C0395));
+}
+
+BOOST_AUTO_TEST_CASE(TestNumberOfTrailingZeroes)
+{
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(1));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(3));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(5));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(7));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(15));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(0xFFFFFFFF));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(0x7FFFFFFF));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(0x00FFFFFF));
+ BOOST_CHECK_EQUAL(0, NumberOfTrailingZerosI32(0x006C0395));
+
+ BOOST_CHECK_EQUAL(1, NumberOfTrailingZerosI32(2));
+
+ BOOST_CHECK_EQUAL(2, NumberOfTrailingZerosI32(4));
+ BOOST_CHECK_EQUAL(2, NumberOfTrailingZerosI32(12));
+
+ BOOST_CHECK_EQUAL(3, NumberOfTrailingZerosI32(8));
+
+ BOOST_CHECK_EQUAL(20, NumberOfTrailingZerosI32(0xFFF00000));
+ BOOST_CHECK_EQUAL(20, NumberOfTrailingZerosI32(0x00F00000));
+ BOOST_CHECK_EQUAL(20, NumberOfTrailingZerosI32(0x00700000));
+ BOOST_CHECK_EQUAL(20, NumberOfTrailingZerosI32(0x80700000));
+
+ BOOST_CHECK_EQUAL(22, NumberOfTrailingZerosI32(0x00400000));
+ BOOST_CHECK_EQUAL(22, NumberOfTrailingZerosI32(0x80400000));
+ BOOST_CHECK_EQUAL(22, NumberOfTrailingZerosI32(0x10400000));
+
+ BOOST_CHECK_EQUAL(23, NumberOfTrailingZerosI32(0x00800000));
+ BOOST_CHECK_EQUAL(23, NumberOfTrailingZerosI32(0x80800000));
+ BOOST_CHECK_EQUAL(23, NumberOfTrailingZerosI32(0xFF800000));
+
+ BOOST_CHECK_EQUAL(30, NumberOfTrailingZerosI32(0x40000000));
+ BOOST_CHECK_EQUAL(30, NumberOfTrailingZerosI32(0xC0000000));
+
+ BOOST_CHECK_EQUAL(31, NumberOfTrailingZerosI32(0x80000000));
+
+ BOOST_CHECK_EQUAL(32, NumberOfTrailingZerosI32(0));
+}
+
+BOOST_AUTO_TEST_CASE(TestBitCount)
+{
+ BOOST_CHECK_EQUAL(0, BitCountI32(0));
+
+ for (int j = 0; j < 32; ++j)
+ {
+ const int32_t testNum = 0xFFFFFFFFUL >> (31 - j);
+
+ for (int i = 0; i < (32 - j); ++i)
+ BOOST_CHECK_EQUAL(j + 1, BitCountI32(testNum));
+ }
+
+ for (int j = 0; j < 32; j += 2)
+ {
+ const int32_t testNum = 0xAAAAAAAAUL >> (31 - j);
+
+ for (int i = 0; i < (32 - j); ++i)
+ BOOST_CHECK_EQUAL((j / 2) + 1, BitCountI32(testNum));
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/src/decimal_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/decimal_test.cpp b/modules/platforms/cpp/core-test/src/decimal_test.cpp
new file mode 100644
index 0000000..47fe8fc
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/decimal_test.cpp
@@ -0,0 +1,1101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include <ignite/common/bits.h>
+#include <ignite/common/decimal.h>
+
+using namespace ignite;
+using namespace ignite::common;
+using namespace ignite::common::bits;
+
+template<typename T>
+void CheckOutputSimple(int64_t val)
+{
+ T dec(val);
+
+ std::stringstream ss1;
+ std::stringstream ss2;
+
+ ss1 << val;
+ ss2 << dec;
+
+ BOOST_CHECK_EQUAL(ss1.str(), ss2.str());
+}
+
+template<typename T>
+void CheckInputOutput(const std::string& val)
+{
+ T dec;
+ std::string res;
+
+ std::stringstream ss1;
+ ss1 << val;
+ ss1 >> dec;
+
+ std::stringstream ss2;
+ ss2 << dec;
+ res = ss2.str();
+
+ BOOST_CHECK_EQUAL(val, res);
+}
+
+template<typename T>
+void CheckOutputInput(const T& val)
+{
+ T dec;
+ std::stringstream ss;
+ ss << val;
+ ss >> dec;
+
+ BOOST_CHECK_EQUAL(val, dec);
+}
+
+void CheckDoubleCast(double val)
+{
+ Decimal dec;
+
+ dec.AssignDouble(val);
+
+ BOOST_CHECK_CLOSE(val, dec.ToDouble(), 1E-10);
+}
+
+BOOST_AUTO_TEST_SUITE(DecimalTestSuite)
+
+BOOST_AUTO_TEST_CASE(TestMultiplyBigIntegerArguments)
+{
+ BigInteger bigInt(12345);
+
+ BigInteger res;
+
+ // 152399025
+ bigInt.Multiply(BigInteger(12345), res);
+
+ {
+ const BigInteger::MagArray &mag = res.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 1);
+
+ BOOST_CHECK_EQUAL(mag[0], 152399025ULL);
+ }
+
+ // 152399025
+ bigInt.AssignInt64(12345);
+ bigInt.Multiply(bigInt, res);
+
+ {
+ const BigInteger::MagArray &mag = res.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 1);
+
+ BOOST_CHECK_EQUAL(mag[0], 152399025ULL);
+ }
+
+ // 152399025
+ bigInt.AssignInt64(12345);
+ bigInt.Multiply(BigInteger(12345), bigInt);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 1);
+
+ BOOST_CHECK_EQUAL(mag[0], 152399025ULL);
+ }
+
+ // 152399025
+ bigInt.AssignInt64(12345);
+ bigInt.Multiply(bigInt, bigInt);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 1);
+
+ BOOST_CHECK_EQUAL(mag[0], 152399025ULL);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TestMultiplyBigIntegerBigger)
+{
+ BigInteger bigInt(12345);
+
+ BigInteger buf;
+
+ // 152399025
+ bigInt.Multiply(bigInt, bigInt);
+
+ buf.Assign(bigInt);
+
+ // 3539537889086624823140625
+ // 0002 ED86 BBC3 30D1 DDC6 6111
+ bigInt.Multiply(buf, bigInt);
+ bigInt.Multiply(buf, bigInt);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 3);
+
+ BOOST_CHECK_EQUAL(mag[0], 0xDDC66111);
+ BOOST_CHECK_EQUAL(mag[1], 0xBBC330D1);
+ BOOST_CHECK_EQUAL(mag[2], 0x0002ED86);
+ }
+
+ // 2698355789040138398691723863616167551412718750 ==
+ // 0078 FF9A F760 4E12 4A1F 3179 D038 D455 630F CC9E
+ bigInt.Multiply(BigInteger(32546826734), bigInt);
+ bigInt.Multiply(BigInteger(23423079641), bigInt);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 5);
+
+ BOOST_CHECK_EQUAL(mag[0], 0x630FCC9E);
+ BOOST_CHECK_EQUAL(mag[1], 0xD038D455);
+ BOOST_CHECK_EQUAL(mag[2], 0x4A1F3179);
+ BOOST_CHECK_EQUAL(mag[3], 0xF7604E12);
+ BOOST_CHECK_EQUAL(mag[4], 0x0078FF9A);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TestPowBigInteger)
+{
+ BigInteger bigInt(12345);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 1);
+
+ BOOST_CHECK_EQUAL(mag[0], 12345);
+ }
+
+ // 152399025
+ bigInt.Pow(2);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 1);
+
+ BOOST_CHECK_EQUAL(mag[0], 152399025ULL);
+ }
+
+ // 3539537889086624823140625
+ // 0002 ED86 BBC3 30D1 DDC6 6111
+ bigInt.Pow(3);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 3);
+
+ BOOST_CHECK_EQUAL(mag[0], 0xDDC66111);
+ BOOST_CHECK_EQUAL(mag[1], 0xBBC330D1);
+ BOOST_CHECK_EQUAL(mag[2], 0x0002ED86);
+ }
+
+ //3086495556566025694024226933269611093366465997140345415945924110519533775
+ //2241867322136254278528975546698722592953892009291022792452635153187272387
+ //9105398830363346664660724134489229239181447334384883937966927158758068117
+ //094808258116245269775390625
+ //
+ // 0000 B4D0 1355 772E
+ // C174 C5F3 B840 74ED 6A54 B544 48E1 E308 6A80 6050 7D37 A56F
+ // 54E6 FF91 13FF 7B0A 455C F649 F4CD 37D0 C5B0 0507 1BFD 9083
+ // 8F13 08B4 D962 08FC FBC0 B5AB F9F9 06C9 94B3 9715 8C43 C94F
+ // 4891 09E5 57AA 66C9 A4F4 3494 A938 89FE 87AF 9056 7D90 17A1
+ bigInt.Pow(10);
+
+ {
+ const BigInteger::MagArray &mag = bigInt.GetMagnitude();
+
+ BOOST_CHECK_EQUAL(mag.GetSize(), 26);
+
+ BOOST_CHECK_EQUAL(mag[0], 0x7D9017A1);
+ BOOST_CHECK_EQUAL(mag[1], 0x87AF9056);
+ BOOST_CHECK_EQUAL(mag[2], 0xA93889FE);
+ BOOST_CHECK_EQUAL(mag[3], 0xA4F43494);
+ BOOST_CHECK_EQUAL(mag[4], 0x57AA66C9);
+ BOOST_CHECK_EQUAL(mag[5], 0x489109E5);
+ BOOST_CHECK_EQUAL(mag[6], 0x8C43C94F);
+ BOOST_CHECK_EQUAL(mag[7], 0x94B39715);
+ BOOST_CHECK_EQUAL(mag[8], 0xF9F906C9);
+ BOOST_CHECK_EQUAL(mag[9], 0xFBC0B5AB);
+ BOOST_CHECK_EQUAL(mag[10], 0xD96208FC);
+ BOOST_CHECK_EQUAL(mag[11], 0x8F1308B4);
+ BOOST_CHECK_EQUAL(mag[12], 0x1BFD9083);
+ BOOST_CHECK_EQUAL(mag[13], 0xC5B00507);
+ BOOST_CHECK_EQUAL(mag[14], 0xF4CD37D0);
+ BOOST_CHECK_EQUAL(mag[15], 0x455CF649);
+ BOOST_CHECK_EQUAL(mag[16], 0x13FF7B0A);
+ BOOST_CHECK_EQUAL(mag[17], 0x54E6FF91);
+ BOOST_CHECK_EQUAL(mag[18], 0x7D37A56F);
+ BOOST_CHECK_EQUAL(mag[19], 0x6A806050);
+ BOOST_CHECK_EQUAL(mag[20], 0x48E1E308);
+ BOOST_CHECK_EQUAL(mag[21], 0x6A54B544);
+ BOOST_CHECK_EQUAL(mag[22], 0xB84074ED);
+ BOOST_CHECK_EQUAL(mag[23], 0xC174C5F3);
+ BOOST_CHECK_EQUAL(mag[24], 0x1355772E);
+ BOOST_CHECK_EQUAL(mag[25], 0x0000B4D0);
+ }
+
+ bigInt.AssignInt64(-1);
+
+ bigInt.Pow(57298735);
+ BOOST_REQUIRE_EQUAL(bigInt.ToInt64(), -1);
+
+ bigInt.Pow(325347312);
+ BOOST_REQUIRE_EQUAL(bigInt.ToInt64(), 1);
+
+ bigInt.AssignInt64(2);
+
+ bigInt.Pow(10);
+ BOOST_REQUIRE_EQUAL(bigInt.ToInt64(), 1024);
+
+ bigInt.AssignInt64(-2);
+
+ bigInt.Pow(10);
+ BOOST_REQUIRE_EQUAL(bigInt.ToInt64(), 1024);
+
+ bigInt.AssignInt64(2);
+
+ bigInt.Pow(11);
+ BOOST_REQUIRE_EQUAL(bigInt.ToInt64(), 2048);
+
+ bigInt.AssignInt64(-2);
+
+ bigInt.Pow(11);
+ BOOST_REQUIRE_EQUAL(bigInt.ToInt64(), -2048);
+}
+
+BOOST_AUTO_TEST_CASE(TestMultiplyDivideSimple)
+{
+ BigInteger val;
+ BigInteger res;
+ BigInteger rem;
+
+ val.AssignInt64(23225462820950625LL);
+
+ // 23225462820 and 950625
+ BigInteger bi1;
+ BigInteger bi2;
+ val.Divide(BigInteger(1000000), bi1, bi2);
+
+ // 23225 and 462820
+ BigInteger bi3;
+ BigInteger bi4;
+ bi1.Divide(BigInteger(1000000), bi3, bi4);
+
+ BOOST_CHECK_EQUAL(bi2.ToInt64(), 950625LL);
+ BOOST_CHECK_EQUAL(bi3.ToInt64(), 23225LL);
+ BOOST_CHECK_EQUAL(bi4.ToInt64(), 462820LL);
+
+ BigInteger(0).Divide(BigInteger(1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(0));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(0).Divide(BigInteger(100), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(0));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(0).Divide(BigInteger(-1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(0));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(0).Divide(BigInteger(-100), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(0));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(1).Divide(BigInteger(1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(1));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(10).Divide(BigInteger(1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(10));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(-1).Divide(BigInteger(1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(-1));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(-10).Divide(BigInteger(1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(-10));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(1).Divide(BigInteger(-1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(-1));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(10).Divide(BigInteger(-1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(-10));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(-1).Divide(BigInteger(-1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(1));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(-10).Divide(BigInteger(-1), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(10));
+ BOOST_CHECK_EQUAL(rem, BigInteger(0));
+
+ BigInteger(123456789).Divide(BigInteger(1000), res);
+ BOOST_CHECK_EQUAL(res, BigInteger(123456));
+
+ val.AssignInt64(79823695862);
+ val.Divide(val, res);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(1));
+
+ val.AssignInt64(28658345673);
+ val.Divide(val, val);
+
+ BOOST_CHECK_EQUAL(val, BigInteger(1));
+
+ val.AssignInt64(-97598673406);
+ val.Divide(val, res, val);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(1));
+ BOOST_CHECK_EQUAL(val, BigInteger(0));
+
+ val.AssignInt64(1);
+ val.Divide(val, res, val);
+
+ BOOST_CHECK_EQUAL(res, BigInteger(1));
+ BOOST_CHECK_EQUAL(val, BigInteger(0));
+}
+
+BOOST_AUTO_TEST_CASE(TestDivideBigger)
+{
+ BigInteger res;
+ BigInteger rem;
+
+ BigInteger("4790467782742318458842833081").Divide(BigInteger(1000000000000000000LL), res, rem);
+
+ BOOST_CHECK_EQUAL(res.ToInt64(), 4790467782LL);
+ BOOST_CHECK_EQUAL(rem.ToInt64(), 742318458842833081LL);
+
+ BigInteger("4790467782742318458842833081").Divide(BigInteger("10000000000000000000"), res, rem);
+
+ BOOST_CHECK_EQUAL(res.ToInt64(), 479046778LL);
+ BOOST_CHECK_EQUAL(rem.ToInt64(), 2742318458842833081LL);
+
+ BigInteger("328569986734256745892025106351608546013457217305539845689265945043650274304152384502658961485730864386").Divide(
+ BigInteger("759823640567289574925305534862590863490856903465"), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger("432429275942170114314334535709873138296890293268042448"));
+ BOOST_CHECK_EQUAL(rem, BigInteger("725289323707320757244048053769339286218272582066"));
+
+ BigInteger("5789420569340865906230645903456092386459628364580763804659834658960883465807263084659832648768603645").Divide(
+ BigInteger("-29064503640646565660609983646665763458768340596340586"), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger("-199192136253942064949205579447876757418653967046"));
+ BOOST_CHECK_EQUAL(rem, BigInteger("-9693519879390725820633207073869515731754969332274689"));
+
+ BigInteger("-107519074510758034695616045096493659264398569023607895679428769875976987594876903458769799098378994985793874569869348579").Divide(
+ BigInteger("197290846190263940610876503491586943095983984894898998999751636576150263056012501"), res, rem);
+
+ BOOST_CHECK_EQUAL(res, BigInteger("-544977512069001243499439196429495600701"));
+ BOOST_CHECK_EQUAL(rem, BigInteger("-66382358009926062210728796777352226675944219851838448875365359123421443108985378"));
+
+ BigInteger("9739565432896546050040656034658762836457836886868678345021405632645902354063045608267340568346582").Divide(
+ BigInteger("8263050146508634250640862503465899340625908694088569038"), res);
+
+ BOOST_CHECK_EQUAL(res, BigInteger("1178688893351540421358600789386475098289416"));
+}
+
+BOOST_AUTO_TEST_CASE(TestOutputSimpleBigInteger)
+{
+ CheckOutputSimple<BigInteger>(0);
+
+ CheckOutputSimple<BigInteger>(1);
+ CheckOutputSimple<BigInteger>(9);
+ CheckOutputSimple<BigInteger>(10);
+ CheckOutputSimple<BigInteger>(11);
+ CheckOutputSimple<BigInteger>(19);
+ CheckOutputSimple<BigInteger>(123);
+ CheckOutputSimple<BigInteger>(1234);
+ CheckOutputSimple<BigInteger>(12345);
+ CheckOutputSimple<BigInteger>(123456);
+ CheckOutputSimple<BigInteger>(1234567);
+ CheckOutputSimple<BigInteger>(12345678);
+ CheckOutputSimple<BigInteger>(123456789);
+ CheckOutputSimple<BigInteger>(1234567890);
+ CheckOutputSimple<BigInteger>(12345678909);
+ CheckOutputSimple<BigInteger>(123456789098);
+ CheckOutputSimple<BigInteger>(1234567890987);
+ CheckOutputSimple<BigInteger>(12345678909876);
+ CheckOutputSimple<BigInteger>(123456789098765);
+ CheckOutputSimple<BigInteger>(1234567890987654);
+ CheckOutputSimple<BigInteger>(12345678909876543);
+ CheckOutputSimple<BigInteger>(123456789098765432);
+ CheckOutputSimple<BigInteger>(1234567890987654321);
+ CheckOutputSimple<BigInteger>(999999999999999999LL);
+ CheckOutputSimple<BigInteger>(999999999099999999LL);
+ CheckOutputSimple<BigInteger>(1000000000000000000LL);
+ CheckOutputSimple<BigInteger>(1000000000000000001LL);
+ CheckOutputSimple<BigInteger>(1000000005000000000LL);
+ CheckOutputSimple<BigInteger>(INT64_MAX);
+
+ CheckOutputSimple<BigInteger>(-1);
+ CheckOutputSimple<BigInteger>(-9);
+ CheckOutputSimple<BigInteger>(-10);
+ CheckOutputSimple<BigInteger>(-11);
+ CheckOutputSimple<BigInteger>(-19);
+ CheckOutputSimple<BigInteger>(-123);
+ CheckOutputSimple<BigInteger>(-1234);
+ CheckOutputSimple<BigInteger>(-12345);
+ CheckOutputSimple<BigInteger>(-123456);
+ CheckOutputSimple<BigInteger>(-1234567);
+ CheckOutputSimple<BigInteger>(-12345678);
+ CheckOutputSimple<BigInteger>(-123456789);
+ CheckOutputSimple<BigInteger>(-1234567890);
+ CheckOutputSimple<BigInteger>(-12345678909);
+ CheckOutputSimple<BigInteger>(-123456789098);
+ CheckOutputSimple<BigInteger>(-1234567890987);
+ CheckOutputSimple<BigInteger>(-12345678909876);
+ CheckOutputSimple<BigInteger>(-123456789098765);
+ CheckOutputSimple<BigInteger>(-1234567890987654);
+ CheckOutputSimple<BigInteger>(-12345678909876543);
+ CheckOutputSimple<BigInteger>(-123456789098765432);
+ CheckOutputSimple<BigInteger>(-1234567890987654321);
+ CheckOutputSimple<BigInteger>(-999999999999999999LL);
+ CheckOutputSimple<BigInteger>(-999999999999999999LL);
+ CheckOutputSimple<BigInteger>(-1000000000000000000LL);
+ CheckOutputSimple<BigInteger>(-1000000000000000001LL);
+ CheckOutputSimple<BigInteger>(-1000000000000000000LL);
+ CheckOutputSimple<BigInteger>(INT64_MIN);
+}
+
+BOOST_AUTO_TEST_CASE(TestOutputSimpleDecimal)
+{
+ CheckOutputSimple<Decimal>(0);
+
+ CheckOutputSimple<Decimal>(1);
+ CheckOutputSimple<Decimal>(9);
+ CheckOutputSimple<Decimal>(10);
+ CheckOutputSimple<Decimal>(11);
+ CheckOutputSimple<Decimal>(19);
+ CheckOutputSimple<Decimal>(123);
+ CheckOutputSimple<Decimal>(1234);
+ CheckOutputSimple<Decimal>(12345);
+ CheckOutputSimple<Decimal>(123456);
+ CheckOutputSimple<Decimal>(1234567);
+ CheckOutputSimple<Decimal>(12345678);
+ CheckOutputSimple<Decimal>(123456789);
+ CheckOutputSimple<Decimal>(1234567890);
+ CheckOutputSimple<Decimal>(12345678909);
+ CheckOutputSimple<Decimal>(123456789098);
+ CheckOutputSimple<Decimal>(1234567890987);
+ CheckOutputSimple<Decimal>(12345678909876);
+ CheckOutputSimple<Decimal>(123456789098765);
+ CheckOutputSimple<Decimal>(1234567890987654);
+ CheckOutputSimple<Decimal>(12345678909876543);
+ CheckOutputSimple<Decimal>(123456789098765432);
+ CheckOutputSimple<Decimal>(1234567890987654321);
+ CheckOutputSimple<Decimal>(999999999999999999LL);
+ CheckOutputSimple<Decimal>(999999999099999999LL);
+ CheckOutputSimple<Decimal>(1000000000000000000LL);
+ CheckOutputSimple<Decimal>(1000000000000000001LL);
+ CheckOutputSimple<Decimal>(1000000005000000000LL);
+ CheckOutputSimple<Decimal>(INT64_MAX);
+
+ CheckOutputSimple<Decimal>(-1);
+ CheckOutputSimple<Decimal>(-9);
+ CheckOutputSimple<Decimal>(-10);
+ CheckOutputSimple<Decimal>(-11);
+ CheckOutputSimple<Decimal>(-19);
+ CheckOutputSimple<Decimal>(-123);
+ CheckOutputSimple<Decimal>(-1234);
+ CheckOutputSimple<Decimal>(-12345);
+ CheckOutputSimple<Decimal>(-123456);
+ CheckOutputSimple<Decimal>(-1234567);
+ CheckOutputSimple<Decimal>(-12345678);
+ CheckOutputSimple<Decimal>(-123456789);
+ CheckOutputSimple<Decimal>(-1234567890);
+ CheckOutputSimple<Decimal>(-12345678909);
+ CheckOutputSimple<Decimal>(-123456789098);
+ CheckOutputSimple<Decimal>(-1234567890987);
+ CheckOutputSimple<Decimal>(-12345678909876);
+ CheckOutputSimple<Decimal>(-123456789098765);
+ CheckOutputSimple<Decimal>(-1234567890987654);
+ CheckOutputSimple<Decimal>(-12345678909876543);
+ CheckOutputSimple<Decimal>(-123456789098765432);
+ CheckOutputSimple<Decimal>(-1234567890987654321);
+ CheckOutputSimple<Decimal>(-999999999999999999LL);
+ CheckOutputSimple<Decimal>(-999999999099999999LL);
+ CheckOutputSimple<Decimal>(-1000000000000000000LL);
+ CheckOutputSimple<Decimal>(-1000000000000000001LL);
+ CheckOutputSimple<Decimal>(-1000000005000000000LL);
+ CheckOutputSimple<Decimal>(INT64_MIN);
+}
+BOOST_AUTO_TEST_CASE(TestInputOutputSimpleBigInteger)
+{
+ CheckInputOutput<BigInteger>("0");
+ CheckInputOutput<BigInteger>("1");
+ CheckInputOutput<BigInteger>("2");
+ CheckInputOutput<BigInteger>("9");
+ CheckInputOutput<BigInteger>("10");
+ CheckInputOutput<BigInteger>("1123");
+ CheckInputOutput<BigInteger>("64539472569345602304");
+ CheckInputOutput<BigInteger>("2376926357280573482539570263854");
+ CheckInputOutput<BigInteger>("407846050973948576230645736487560936425876349857823587643258934569364587268645394725693456023046037490024067294087609279");
+
+ CheckInputOutput<BigInteger>("1000000000000");
+ CheckInputOutput<BigInteger>("1000000000000000000000000000");
+ CheckInputOutput<BigInteger>("100000000000000000000000000000000000000000000000000000000000");
+
+ CheckInputOutput<BigInteger>("99999999999999");
+ CheckInputOutput<BigInteger>("99999999999999999999999999999999");
+ CheckInputOutput<BigInteger>("9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+
+ CheckInputOutput<BigInteger>("-1");
+ CheckInputOutput<BigInteger>("-2");
+ CheckInputOutput<BigInteger>("-9");
+ CheckInputOutput<BigInteger>("-10");
+ CheckInputOutput<BigInteger>("-1123");
+ CheckInputOutput<BigInteger>("-64539472569345602304");
+ CheckInputOutput<BigInteger>("-2376926357280573482539570263854");
+ CheckInputOutput<BigInteger>("-407846050973948576230645736487560936425876349857823587643258934569364587268645394725693456023046037490024067294087609279");
+
+ CheckInputOutput<BigInteger>("-1000000000000");
+ CheckInputOutput<BigInteger>("-1000000000000000000000000000");
+ CheckInputOutput<BigInteger>("-100000000000000000000000000000000000000000000000000000000000");
+
+ CheckInputOutput<BigInteger>("-99999999999999");
+ CheckInputOutput<BigInteger>("-99999999999999999999999999999999");
+ CheckInputOutput<BigInteger>("-9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+}
+
+BOOST_AUTO_TEST_CASE(TestInputOutputSimpleDecimal)
+{
+ CheckInputOutput<Decimal>("0");
+ CheckInputOutput<Decimal>("1");
+ CheckInputOutput<Decimal>("2");
+ CheckInputOutput<Decimal>("9");
+ CheckInputOutput<Decimal>("10");
+ CheckInputOutput<Decimal>("1123");
+ CheckInputOutput<Decimal>("64539472569345602304");
+ CheckInputOutput<Decimal>("2376926357280573482539570263854");
+ CheckInputOutput<Decimal>("407846050973948576230645736487560936425876349857823587643258934569364587268645394725693456023046037490024067294087609279");
+
+ CheckInputOutput<Decimal>("1000000000000");
+ CheckInputOutput<Decimal>("1000000000000000000000000000");
+ CheckInputOutput<Decimal>("100000000000000000000000000000000000000000000000000000000000");
+
+ CheckInputOutput<Decimal>("99999999999999");
+ CheckInputOutput<Decimal>("99999999999999999999999999999999");
+ CheckInputOutput<Decimal>("9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+
+ CheckInputOutput<Decimal>("-1");
+ CheckInputOutput<Decimal>("-2");
+ CheckInputOutput<Decimal>("-9");
+ CheckInputOutput<Decimal>("-10");
+ CheckInputOutput<Decimal>("-1123");
+ CheckInputOutput<Decimal>("-64539472569345602304");
+ CheckInputOutput<Decimal>("-2376926357280573482539570263854");
+ CheckInputOutput<Decimal>("-407846050973948576230645736487560936425876349857823587643258934569364587268645394725693456023046037490024067294087609279");
+
+ CheckInputOutput<Decimal>("-1000000000000");
+ CheckInputOutput<Decimal>("-1000000000000000000000000000");
+ CheckInputOutput<Decimal>("-100000000000000000000000000000000000000000000000000000000000");
+
+ CheckInputOutput<Decimal>("-99999999999999");
+ CheckInputOutput<Decimal>("-99999999999999999999999999999999");
+ CheckInputOutput<Decimal>("-9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+
+ CheckInputOutput<Decimal>("0.1");
+ CheckInputOutput<Decimal>("0.2");
+ CheckInputOutput<Decimal>("0.3");
+ CheckInputOutput<Decimal>("0.4");
+ CheckInputOutput<Decimal>("0.5");
+ CheckInputOutput<Decimal>("0.6");
+ CheckInputOutput<Decimal>("0.7");
+ CheckInputOutput<Decimal>("0.8");
+ CheckInputOutput<Decimal>("0.9");
+ CheckInputOutput<Decimal>("0.01");
+ CheckInputOutput<Decimal>("0.001");
+ CheckInputOutput<Decimal>("0.0001");
+ CheckInputOutput<Decimal>("0.00001");
+ CheckInputOutput<Decimal>("0.000001");
+ CheckInputOutput<Decimal>("0.0000001");
+
+ CheckInputOutput<Decimal>("0.00000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("0.10000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("0.10101010101010101010101010101010101");
+ CheckInputOutput<Decimal>("0.99999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("0.79287502687354897253590684568634528762");
+
+ CheckInputOutput<Decimal>("0.00000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("0.10000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("0.1111111111111111111111111111111111111111111111111111111111");
+ CheckInputOutput<Decimal>("0.9999999999999999999999999999999999999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("0.436589746389567836745873648576289634589763845768268457683762864587684635892768346589629");
+
+ CheckInputOutput<Decimal>("0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("0.10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("0.111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
+ CheckInputOutput<Decimal>("0.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("0.436589746389567836745873648576289634589763845768268457683762864587684635892768346549385700256032605603246580726384075680247634627357023645889629");
+
+ CheckInputOutput<Decimal>("-0.1");
+ CheckInputOutput<Decimal>("-0.2");
+ CheckInputOutput<Decimal>("-0.3");
+ CheckInputOutput<Decimal>("-0.4");
+ CheckInputOutput<Decimal>("-0.5");
+ CheckInputOutput<Decimal>("-0.6");
+ CheckInputOutput<Decimal>("-0.7");
+ CheckInputOutput<Decimal>("-0.8");
+ CheckInputOutput<Decimal>("-0.9");
+ CheckInputOutput<Decimal>("-0.01");
+ CheckInputOutput<Decimal>("-0.001");
+ CheckInputOutput<Decimal>("-0.0001");
+ CheckInputOutput<Decimal>("-0.00001");
+ CheckInputOutput<Decimal>("-0.000001");
+ CheckInputOutput<Decimal>("-0.0000001");
+
+ CheckInputOutput<Decimal>("-0.00000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-0.10000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-0.10101010101010101010101010101010101");
+ CheckInputOutput<Decimal>("-0.99999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("-0.79287502687354897253590684568634528762");
+
+ CheckInputOutput<Decimal>("-0.00000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-0.10000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-0.1111111111111111111111111111111111111111111111111111111111");
+ CheckInputOutput<Decimal>("-0.9999999999999999999999999999999999999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("-0.436589746389567836745873648576289634589763845768268457683762864587684635892768346589629");
+
+ CheckInputOutput<Decimal>("-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-0.10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-0.111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
+ CheckInputOutput<Decimal>("-0.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("-0.436589746389567836745873648576289634589763845768268457683762864587684635892768346549385700256032605603246580726384075680247634627357023645889629");
+
+ CheckInputOutput<Decimal>("1.1");
+ CheckInputOutput<Decimal>("12.21");
+ CheckInputOutput<Decimal>("123.321");
+ CheckInputOutput<Decimal>("1234.4321");
+ CheckInputOutput<Decimal>("12345.54321");
+ CheckInputOutput<Decimal>("123456.654321");
+ CheckInputOutput<Decimal>("1234567.7654321");
+ CheckInputOutput<Decimal>("12345678.87654321");
+ CheckInputOutput<Decimal>("123456789.987654321");
+ CheckInputOutput<Decimal>("1234567890.0987654321");
+ CheckInputOutput<Decimal>("12345678909.90987654321");
+ CheckInputOutput<Decimal>("123456789098.890987654321");
+ CheckInputOutput<Decimal>("1234567890987.7890987654321");
+ CheckInputOutput<Decimal>("12345678909876.67890987654321");
+ CheckInputOutput<Decimal>("123456789098765.567890987654321");
+ CheckInputOutput<Decimal>("1234567890987654.4567890987654321");
+ CheckInputOutput<Decimal>("12345678909876543.34567890987654321");
+ CheckInputOutput<Decimal>("123456789098765432.234567890987654321");
+ CheckInputOutput<Decimal>("1234567890987654321.1234567890987654321");
+ CheckInputOutput<Decimal>("12345678909876543210.01234567890987654321");
+ CheckInputOutput<Decimal>("10000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("111111111111111111111111111111111111111111111111111111111111111111111.11111111111111111111111111111111111111111111111111111111111111");
+ CheckInputOutput<Decimal>("99999999999999999999999999999999999999999999999999999999999999999999.99999999999999999999999999999999999999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("458796987658934265896483756892638456782376482605002747502306790283640563.12017054126750641065780784583204650763485718064875683468568360506340563042567");
+
+ CheckInputOutput<Decimal>("-1.1");
+ CheckInputOutput<Decimal>("-12.21");
+ CheckInputOutput<Decimal>("-123.321");
+ CheckInputOutput<Decimal>("-1234.4321");
+ CheckInputOutput<Decimal>("-12345.54321");
+ CheckInputOutput<Decimal>("-123456.654321");
+ CheckInputOutput<Decimal>("-1234567.7654321");
+ CheckInputOutput<Decimal>("-12345678.87654321");
+ CheckInputOutput<Decimal>("-123456789.987654321");
+ CheckInputOutput<Decimal>("-1234567890.0987654321");
+ CheckInputOutput<Decimal>("-12345678909.90987654321");
+ CheckInputOutput<Decimal>("-123456789098.890987654321");
+ CheckInputOutput<Decimal>("-1234567890987.7890987654321");
+ CheckInputOutput<Decimal>("-12345678909876.67890987654321");
+ CheckInputOutput<Decimal>("-123456789098765.567890987654321");
+ CheckInputOutput<Decimal>("-1234567890987654.4567890987654321");
+ CheckInputOutput<Decimal>("-12345678909876543.34567890987654321");
+ CheckInputOutput<Decimal>("-123456789098765432.234567890987654321");
+ CheckInputOutput<Decimal>("-1234567890987654321.1234567890987654321");
+ CheckInputOutput<Decimal>("-12345678909876543210.01234567890987654321");
+ CheckInputOutput<Decimal>("-10000000000000000000000000000000000000000000000000000000000000.000000000000000000000000000000000000000000000000000000000000001");
+ CheckInputOutput<Decimal>("-111111111111111111111111111111111111111111111111111111111111111111111.11111111111111111111111111111111111111111111111111111111111111");
+ CheckInputOutput<Decimal>("-99999999999999999999999999999999999999999999999999999999999999999999.99999999999999999999999999999999999999999999999999999999999999999999");
+ CheckInputOutput<Decimal>("-458796987658934265896483756892638456782376482605002747502306790283640563.12017054126750641065780784583204650763485718064875683468568360506340563042567");
+}
+
+BOOST_AUTO_TEST_CASE(TestInputSimpleDecimal)
+{
+ CheckOutputInput(Decimal(0));
+
+ CheckOutputInput(Decimal(1));
+ CheckOutputInput(Decimal(9));
+ CheckOutputInput(Decimal(10));
+ CheckOutputInput(Decimal(11));
+ CheckOutputInput(Decimal(19));
+ CheckOutputInput(Decimal(123));
+ CheckOutputInput(Decimal(1234));
+ CheckOutputInput(Decimal(12345));
+ CheckOutputInput(Decimal(123456));
+ CheckOutputInput(Decimal(1234567));
+ CheckOutputInput(Decimal(12345678));
+ CheckOutputInput(Decimal(123456789));
+ CheckOutputInput(Decimal(1234567890));
+ CheckOutputInput(Decimal(12345678909));
+ CheckOutputInput(Decimal(123456789098));
+ CheckOutputInput(Decimal(1234567890987));
+ CheckOutputInput(Decimal(12345678909876));
+ CheckOutputInput(Decimal(123456789098765));
+ CheckOutputInput(Decimal(1234567890987654));
+ CheckOutputInput(Decimal(12345678909876543));
+ CheckOutputInput(Decimal(123456789098765432));
+ CheckOutputInput(Decimal(1234567890987654321));
+ CheckOutputInput(Decimal(999999999999999999LL));
+ CheckOutputInput(Decimal(999999999099999999LL));
+ CheckOutputInput(Decimal(1000000000000000000LL));
+ CheckOutputInput(Decimal(1000000000000000001LL));
+ CheckOutputInput(Decimal(1000000005000000000LL));
+ CheckOutputInput(Decimal(INT64_MAX));
+
+ CheckOutputInput(Decimal(-1));
+ CheckOutputInput(Decimal(-9));
+ CheckOutputInput(Decimal(-10));
+ CheckOutputInput(Decimal(-11));
+ CheckOutputInput(Decimal(-19));
+ CheckOutputInput(Decimal(-123));
+ CheckOutputInput(Decimal(-1234));
+ CheckOutputInput(Decimal(-12345));
+ CheckOutputInput(Decimal(-123456));
+ CheckOutputInput(Decimal(-1234567));
+ CheckOutputInput(Decimal(-12345678));
+ CheckOutputInput(Decimal(-123456789));
+ CheckOutputInput(Decimal(-1234567890));
+ CheckOutputInput(Decimal(-12345678909));
+ CheckOutputInput(Decimal(-123456789098));
+ CheckOutputInput(Decimal(-1234567890987));
+ CheckOutputInput(Decimal(-12345678909876));
+ CheckOutputInput(Decimal(-123456789098765));
+ CheckOutputInput(Decimal(-1234567890987654));
+ CheckOutputInput(Decimal(-12345678909876543));
+ CheckOutputInput(Decimal(-123456789098765432));
+ CheckOutputInput(Decimal(-1234567890987654321));
+ CheckOutputInput(Decimal(-999999999999999999LL));
+ CheckOutputInput(Decimal(-999999999099999999LL));
+ CheckOutputInput(Decimal(-1000000000000000000LL));
+ CheckOutputInput(Decimal(-1000000000000000001LL));
+ CheckOutputInput(Decimal(-1000000005000000000LL));
+ CheckOutputInput(Decimal(INT64_MIN));
+}
+
+BOOST_AUTO_TEST_CASE(TestScalingSmall)
+{
+ Decimal decimal(12345, 2);
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 5);
+
+ decimal.SetScale(0, decimal);
+
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 3);
+
+ BOOST_CHECK_EQUAL(decimal.ToInt64(), 123);
+}
+
+BOOST_AUTO_TEST_CASE(TestScalingBig)
+{
+ BigInteger bigInt(69213205262741);
+
+ Decimal decimal;
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 1);
+
+ // 4790467782742318458842833081
+ bigInt.Multiply(bigInt, bigInt);
+
+ decimal = Decimal(bigInt, 0);
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 28);
+
+ // 22948581577492104846692006446607391554788985798427952561
+ bigInt.Multiply(bigInt, bigInt);
+
+ decimal = Decimal(bigInt, 0);
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 56);
+
+ // 22948581577492104846692006446607391554.788985798427952561
+ decimal = Decimal(bigInt, 18);
+
+ // 22948581577492104846692006446607391554
+ decimal.SetScale(0, decimal);
+
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 38);
+
+ // 22948581.577492104846692006446607391554788985798427952561
+ decimal = Decimal(bigInt, 48);
+
+ // 22948581
+ decimal.SetScale(0, decimal);
+
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 8);
+ BOOST_CHECK_EQUAL(decimal.ToInt64(), 22948581);
+
+ // 636471904553811060306806140254026286906087997856914463925431295610150712
+ // 436301540552945788827650832722026963914694916372255230793492080431332686
+ // 268324254350022490844698008329270553114204362445999680199136593689695140
+ // 0874934591063287320666899465891248127072522251998904759858801
+ bigInt.Pow(5);
+
+ // 63647190455381106.030680614025402628690608799785691446392543129561015071
+ // 243630154055294578882765083272202696391469491637225523079349208043133268
+ // 626832425435002249084469800832927055311420436244599968019913659368969514
+ // 00874934591063287320666899465891248127072522251998904759858801
+ decimal = Decimal(bigInt, 260);
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 277);
+
+ // 63647190455381106
+ decimal.SetScale(0, decimal);
+
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 17);
+ BOOST_CHECK_EQUAL(decimal.ToInt64(), 63647190455381106LL);
+}
+
+BOOST_AUTO_TEST_CASE(TestPrecisionSimple)
+{
+ Decimal test(1);
+
+ BOOST_CHECK_EQUAL(Decimal(-9).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-8).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-7).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-6).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-5).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-4).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-3).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-2).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(-1).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(0).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(1).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(2).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(3).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(4).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(5).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(6).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(7).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(8).GetPrecision(), 1);
+ BOOST_CHECK_EQUAL(Decimal(9).GetPrecision(), 1);
+
+ BOOST_CHECK_EQUAL(Decimal(2147483648LL).GetPrecision(), 10); // 2^31: 10 digits
+ BOOST_CHECK_EQUAL(Decimal(-2147483648LL).GetPrecision(), 10); // -2^31: 10 digits
+ BOOST_CHECK_EQUAL(Decimal(98893745455LL).GetPrecision(), 11); // random: 11 digits
+ BOOST_CHECK_EQUAL(Decimal(3455436789887LL).GetPrecision(), 13); // random: 13 digits
+ BOOST_CHECK_EQUAL(Decimal(140737488355328LL).GetPrecision(), 15); // 2^47: 15 digits
+ BOOST_CHECK_EQUAL(Decimal(-140737488355328LL).GetPrecision(), 15); // -2^47: 15 digits
+ BOOST_CHECK_EQUAL(Decimal(7564232235739573LL).GetPrecision(), 16); // random: 16 digits
+ BOOST_CHECK_EQUAL(Decimal(25335434990002322LL).GetPrecision(), 17); // random: 17 digits
+ BOOST_CHECK_EQUAL(Decimal(9223372036854775807LL).GetPrecision(), 19); // 2^63 - 1: 19 digits
+ BOOST_CHECK_EQUAL(Decimal(-9223372036854775807LL).GetPrecision(), 19); // -2^63 + 1: 19 digits
+}
+
+BOOST_AUTO_TEST_CASE(TestPrecisionChange)
+{
+ BigInteger bigInt(32421);
+
+ //75946938183
+ bigInt.Multiply(BigInteger(2342523), bigInt);
+
+ //4244836901495581620
+ bigInt.Multiply(BigInteger(55892140), bigInt);
+
+ //1361610054778960404282184020
+ bigInt.Multiply(BigInteger(320768521), bigInt);
+
+ //1454144449122723409814375680476734820
+ bigInt.Multiply(BigInteger(1067959541), bigInt);
+
+ //117386322514277938455905731466723946155156640
+ bigInt.Multiply(BigInteger(80725352), bigInt);
+
+ //1173863225142779384559.05731466723946155156640
+ Decimal decimal(bigInt, 23);
+
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), 45);
+ BOOST_CHECK_EQUAL(decimal.GetScale(), 23);
+
+ for (int32_t i = 0; i < decimal.GetScale(); ++i)
+ {
+ decimal.SetScale(i, decimal);
+
+ BOOST_CHECK_EQUAL(decimal.GetPrecision(), decimal.GetPrecision() - decimal.GetScale() + i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TestDoubleCast)
+{
+ CheckDoubleCast(100000000000000.0);
+ CheckDoubleCast(10000000000000.0);
+ CheckDoubleCast(1000000000000.0);
+ CheckDoubleCast(100000000000.0);
+ CheckDoubleCast(10000000000.0);
+ CheckDoubleCast(1000000000.0);
+ CheckDoubleCast(100000000.0);
+ CheckDoubleCast(10000000.0);
+ CheckDoubleCast(1000000.0);
+ CheckDoubleCast(100000.0);
+ CheckDoubleCast(10000.0);
+ CheckDoubleCast(1000.0);
+ CheckDoubleCast(100.0);
+ CheckDoubleCast(10.0);
+ CheckDoubleCast(1.0);
+ CheckDoubleCast(0.1);
+ CheckDoubleCast(0.01);
+ CheckDoubleCast(0.001);
+ CheckDoubleCast(0.0001);
+ CheckDoubleCast(0.00001);
+ CheckDoubleCast(0.000001);
+ CheckDoubleCast(0.0000001);
+ CheckDoubleCast(0.00000001);
+ CheckDoubleCast(0.000000001);
+ CheckDoubleCast(0.0000000001);
+ CheckDoubleCast(0.00000000001);
+ CheckDoubleCast(0.000000000001);
+ CheckDoubleCast(0.00000000000001);
+ CheckDoubleCast(0.000000000000001);
+
+ CheckDoubleCast(2379506093465806.);
+ CheckDoubleCast(172650963870256.3);
+ CheckDoubleCast(63506206502638.57);
+ CheckDoubleCast(8946589364589.763);
+ CheckDoubleCast(896258976348.9568);
+ CheckDoubleCast(28967349256.39428);
+ CheckDoubleCast(2806348972.689369);
+ CheckDoubleCast(975962354.2835845);
+ CheckDoubleCast(96342568.93542342);
+ CheckDoubleCast(6875825.934892387);
+ CheckDoubleCast(314969.6543969458);
+ CheckDoubleCast(32906.02476506344);
+ CheckDoubleCast(9869.643965396453);
+ CheckDoubleCast(779.6932689452953);
+ CheckDoubleCast(75.93592963492326);
+ CheckDoubleCast(8.719654293587452);
+ CheckDoubleCast(.90001236587463439);
+
+ CheckDoubleCast(-235235E-100);
+ CheckDoubleCast(-235235E-90);
+ CheckDoubleCast(-235235E-80);
+ CheckDoubleCast(-235235E-70);
+ CheckDoubleCast(-235235E-60);
+ CheckDoubleCast(-235235E-50);
+ CheckDoubleCast(-235235E-40);
+ CheckDoubleCast(-235235E-30);
+ CheckDoubleCast(-235235E-25);
+ CheckDoubleCast(-235235E-20);
+ CheckDoubleCast(-235235E-15);
+ CheckDoubleCast(-235235E-10);
+ CheckDoubleCast(-235235E-9);
+ CheckDoubleCast(-235235E-8);
+ CheckDoubleCast(-235235E-7);
+ CheckDoubleCast(-235235E-6);
+ CheckDoubleCast(-235235E-5);
+ CheckDoubleCast(-235235E-4);
+ CheckDoubleCast(-235235E-2);
+ CheckDoubleCast(-235235E-1);
+ CheckDoubleCast(-235235);
+ CheckDoubleCast(-235235E+1);
+ CheckDoubleCast(-235235E+2);
+ CheckDoubleCast(-235235E+3);
+ CheckDoubleCast(-235235E+4);
+ CheckDoubleCast(-235235E+5);
+ CheckDoubleCast(-235235E+6);
+ CheckDoubleCast(-235235E+7);
+ CheckDoubleCast(-235235E+8);
+ CheckDoubleCast(-235235E+9);
+ CheckDoubleCast(-235235E+10);
+ CheckDoubleCast(-235235E+15);
+ CheckDoubleCast(-235235E+20);
+ CheckDoubleCast(-235235E+25);
+ CheckDoubleCast(-235235E+30);
+ CheckDoubleCast(-235235E+40);
+ CheckDoubleCast(-235235E+50);
+ CheckDoubleCast(-235235E+60);
+ CheckDoubleCast(-235235E+70);
+ CheckDoubleCast(-235235E+80);
+ CheckDoubleCast(-235235E+90);
+ CheckDoubleCast(-235235E+100);
+
+ CheckDoubleCast(-2379506093465806.);
+ CheckDoubleCast(-172650963870256.3);
+ CheckDoubleCast(-63506206502638.57);
+ CheckDoubleCast(-8946589364589.763);
+ CheckDoubleCast(-896258976348.9568);
+ CheckDoubleCast(-28967349256.39428);
+ CheckDoubleCast(-2806348972.689369);
+ CheckDoubleCast(-975962354.2835845);
+ CheckDoubleCast(-96342568.93542342);
+ CheckDoubleCast(-6875825.934892387);
+ CheckDoubleCast(-314969.6543969458);
+ CheckDoubleCast(-32906.02476506344);
+ CheckDoubleCast(-9869.643965396453);
+ CheckDoubleCast(-779.6932689452953);
+ CheckDoubleCast(-75.93592963492326);
+ CheckDoubleCast(-8.719654293587452);
+ CheckDoubleCast(-.90001236587463439);
+
+ CheckDoubleCast(-100000000000000.0);
+ CheckDoubleCast(-10000000000000.0);
+ CheckDoubleCast(-1000000000000.0);
+ CheckDoubleCast(-100000000000.0);
+ CheckDoubleCast(-10000000000.0);
+ CheckDoubleCast(-1000000000.0);
+ CheckDoubleCast(-100000000.0);
+ CheckDoubleCast(-10000000.0);
+ CheckDoubleCast(-1000000.0);
+ CheckDoubleCast(-100000.0);
+ CheckDoubleCast(-10000.0);
+ CheckDoubleCast(-1000.0);
+ CheckDoubleCast(-100.0);
+ CheckDoubleCast(-10.0);
+ CheckDoubleCast(-1.0);
+ CheckDoubleCast(-0.1);
+ CheckDoubleCast(-0.01);
+ CheckDoubleCast(-0.001);
+ CheckDoubleCast(-0.0001);
+ CheckDoubleCast(-0.00001);
+ CheckDoubleCast(-0.000001);
+ CheckDoubleCast(-0.0000001);
+ CheckDoubleCast(-0.00000001);
+ CheckDoubleCast(-0.000000001);
+ CheckDoubleCast(-0.0000000001);
+ CheckDoubleCast(-0.00000000001);
+ CheckDoubleCast(-0.000000000001);
+ CheckDoubleCast(-0.00000000000001);
+ CheckDoubleCast(-0.000000000000001);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file