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

Reply via email to