
#include <cstdint>
#include <limits>
#include <random>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>

#define BOOST_TEST_MAIN  1
#include <boost/test/unit_test.hpp>

#include "fixed.h"

// Helper macros
#define VALUE_CHECK(val)                    \
    output.str("");                         \
    output << value;                        \
    /*std::cout << "CHECK: " << output.str() << " == " << val << std::endl;*/ \
    BOOST_CHECK(output.str() == val);

#define PARSE_VALUE_CHECK(val)              \
    value.parse(input);                     \
    output.str("");                         \
    output << value;                        \
    /*std::cout << "CHECK: " << output.str() << " == " << val << std::endl;*/ \
    BOOST_CHECK(output.str() == val);

// "in" is the string to be parsed
// "val" is the expected serialized output
#define PARSE_VALUE_CHECK_2(in, val)        \
    input = in;                             \
    value.parse(input);                     \
    output.str("");                         \
    output << value;                        \
    /*std::cout << "CHECK: " << output.str() << " == " << val << std::endl;*/ \
    BOOST_CHECK(output.str() == val);

#define PARSE_EXCEPTION_CHECK               \
    exception = false;                      \
    try                                     \
    {                                       \
        value.parse(input);                 \
    }                                       \
    catch (const std::out_of_range& exp)    \
    {                                       \
        exception = true;                   \
    }                                       \
    BOOST_CHECK(exception);

BOOST_AUTO_TEST_CASE(t000)
{
    /* TEST CASE 0: Check storage sizes (in bytes) of all predefined fixed 
     * point types.
     */
    fixed_8_8  f_8_8;
    fixed_8_32 f_8_32;
    fixed_8_16 f_8_16;
    fixed_8_64 f_8_64;
    fixed_8_128 f_8_128;
    BOOST_CHECK(sizeof(f_8_8)  == 2);
    BOOST_CHECK(sizeof(f_8_16) == 4);
    BOOST_CHECK(sizeof(f_8_32) == 8);
    BOOST_CHECK(sizeof(f_8_64) == 16);
    BOOST_CHECK(sizeof(f_8_128) == 32);
    
    fixed_16_8  f_16_8;
    fixed_16_16 f_16_16;
    fixed_16_32 f_16_32;
    fixed_16_64 f_16_64;
    fixed_16_128 f_16_128;
    BOOST_CHECK(sizeof(f_16_8)  == 4);
    BOOST_CHECK(sizeof(f_16_16) == 4);
    BOOST_CHECK(sizeof(f_16_32) == 8);
    BOOST_CHECK(sizeof(f_16_64) == 16);
    BOOST_CHECK(sizeof(f_16_128) == 32);
    
    fixed_32_8  f_32_8;
    fixed_32_16 f_32_16;
    fixed_32_32 f_32_32;
    fixed_32_64 f_32_64;
    fixed_32_128 f_32_128;
    BOOST_CHECK(sizeof(f_32_8)  == 8);
    BOOST_CHECK(sizeof(f_32_16) == 8);
    BOOST_CHECK(sizeof(f_32_32) == 8);
    BOOST_CHECK(sizeof(f_32_64) == 16);
    BOOST_CHECK(sizeof(f_32_128) == 32);
    
    fixed_64_8  f_64_8;
    fixed_64_16 f_64_16;
    fixed_64_32 f_64_32;
    fixed_64_64 f_64_64;
    fixed_64_128 f_64_128;
    BOOST_CHECK(sizeof(f_64_8)  == 16);
    BOOST_CHECK(sizeof(f_64_16) == 16);
    BOOST_CHECK(sizeof(f_64_32) == 16);
    BOOST_CHECK(sizeof(f_64_64) == 16);
    BOOST_CHECK(sizeof(f_64_128) == 32);
    
    fixed_128_8  f_128_8;
    fixed_128_16 f_128_16;
    fixed_128_32 f_128_32;
    fixed_128_64 f_128_64;
    fixed_128_128 f_128_128;
    BOOST_CHECK(sizeof(f_128_8)  == 32);
    BOOST_CHECK(sizeof(f_128_16) == 32);
    BOOST_CHECK(sizeof(f_128_32) == 32);
    BOOST_CHECK(sizeof(f_128_64) == 32);
    BOOST_CHECK(sizeof(f_128_128) == 32);
}

BOOST_AUTO_TEST_CASE(t001)
{
    /* TEST CASE 1: Test basic comparisons
     */ 
    fixed_128_128 val1(100, 1, 0);
    fixed_128_128 val2(100, 1);
    
    BOOST_CHECK(  (val1 == val2));
    BOOST_CHECK(! (val1 != val2));
    BOOST_CHECK(! (val1 > val2));
    BOOST_CHECK(! (val1 < val2));
    BOOST_CHECK(  (val1 >= val2));
    BOOST_CHECK(  (val1 <= val2));
    
    val2.assignUnscaledFrac(100, 1, 18);
    
    BOOST_CHECK(! (val1 == val2));
    BOOST_CHECK(  (val1 != val2));
    BOOST_CHECK(  (val1 > val2));
    BOOST_CHECK(! (val1 < val2));
    BOOST_CHECK(  (val1 >= val2));
    BOOST_CHECK(! (val1 <= val2));
}

BOOST_AUTO_TEST_CASE(t002)
{
    /* TEST CASE 2: Test parsing with leading zeros.
     */ 
    fixed_128_128 val1;
    fixed_128_128 val2;

    // 1
    val1.assign(1, 20000000000000000000000000000000000000_u128);
    val2.parse("1.2");
    BOOST_CHECK(val1 == val2);

    // 2
    val1.assign(1, 2000000000000000000000000000000000000_u128);
    val2.parse("1.02");
    BOOST_CHECK(val1 == val2);

    // 3
    val1.assign(1, 200000000000000000000000000000000000_u128);
    val2.parse("1.002");
    BOOST_CHECK(val1 == val2);

    // 4
    val1.assign(1, 20000000000000000000000000000000000_u128);
    val2.parse("1.0002");
    BOOST_CHECK(val1 == val2);

    // 5
    val1.assign(1, 2000000000000000000000000000000000_u128);
    val2.parse("1.00002");
    BOOST_CHECK(val1 == val2);

    // 6
    val1.assign(1, 200000000000000000000000000000000_u128);
    val2.parse("1.000002");
    BOOST_CHECK(val1 == val2);

    // 7
    val1.assign(1, 20000000000000000000000000000000_u128);
    val2.parse("1.0000002");
    BOOST_CHECK(val1 == val2);

    // 8
    val1.assign(1, 2000000000000000000000000000000_u128);
    val2.parse("1.00000002");
    BOOST_CHECK(val1 == val2);

    // 9
    val1.assign(1, 200000000000000000000000000000_u128);
    val2.parse("1.000000002");
    BOOST_CHECK(val1 == val2);

    // 10
    val1.assign(1, 20000000000000000000000000000_u128);
    val2.parse("1.0000000002");
    BOOST_CHECK(val1 == val2);

    // 11
    val1.assign(1, 2000000000000000000000000000_u128);
    val2.parse("1.00000000002");
    BOOST_CHECK(val1 == val2);

    // 12
    val1.assign(1, 200000000000000000000000000_u128);
    val2.parse("1.000000000002");
    BOOST_CHECK(val1 == val2);

    // 13
    val1.assign(1, 20000000000000000000000000_u128);
    val2.parse("1.0000000000002");
    BOOST_CHECK(val1 == val2);

    // 14
    val1.assign(1, 2000000000000000000000000_u128);
    val2.parse("1.00000000000002");
    BOOST_CHECK(val1 == val2);

    // 15
    val1.assign(1, 200000000000000000000000_u128);
    val2.parse("1.000000000000002");
    BOOST_CHECK(val1 == val2);

    // 16
    val1.assign(1, 20000000000000000000000_u128);
    val2.parse("1.0000000000000002");
    BOOST_CHECK(val1 == val2);

    // 17
    val1.assign(1, 2000000000000000000000_u128);
    val2.parse("1.00000000000000002");
    BOOST_CHECK(val1 == val2);

    // 18
    val1.assign(1, 200000000000000000000_u128);
    val2.parse("1.000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 19
    val1.assign(1, 20000000000000000000_u128);
    val2.parse("1.0000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 20
    val1.assign(1, 2000000000000000000_u128);
    val2.parse("1.00000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 21
    val1.assign(1, 200000000000000000_u128);
    val2.parse("1.000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 22
    val1.assign(1, 20000000000000000_u128);
    val2.parse("1.0000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 23
    val1.assign(1, 2000000000000000_u128);
    val2.parse("1.00000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 24
    val1.assign(1, 200000000000000_u128);
    val2.parse("1.000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 25
    val1.assign(1, 20000000000000_u128);
    val2.parse("1.0000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 26
    val1.assign(1, 2000000000000_u128);
    val2.parse("1.00000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 27
    val1.assign(1, 200000000000_u128);
    val2.parse("1.000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 28
    val1.assign(1, 20000000000_u128);
    val2.parse("1.0000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 29
    val1.assign(1, 2000000000_u128);
    val2.parse("1.00000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 30
    val1.assign(1, 200000000_u128);
    val2.parse("1.000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 31
    val1.assign(1, 20000000_u128);
    val2.parse("1.0000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 32
    val1.assign(1, 2000000_u128);
    val2.parse("1.00000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 33
    val1.assign(1, 200000_u128);
    val2.parse("1.000000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 34
    val1.assign(1, 20000_u128);
    val2.parse("1.0000000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 35
    val1.assign(1, 2000_u128);
    val2.parse("1.00000000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 36
    val1.assign(1, 200_u128);
    val2.parse("1.000000000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 37
    val1.assign(1, 20_u128);
    val2.parse("1.0000000000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);

    // 38
    val1.assign(1, 2_u128);
    val2.parse("1.00000000000000000000000000000000000002");
    BOOST_CHECK(val1 == val2);
}

BOOST_AUTO_TEST_CASE(t003)
{
    /* TEST CASE 3: Test parsing and printing randomly generated values
     */ 
    using theType = fixed_128_128;

    uint32_t NUMBER = 1000000;
    uint64_t SEED = 0xDEADBEEF123;
    
    std::random_device dev;
    std::mt19937 rng;
    rng.seed(SEED);
    
    std::uniform_int_distribution<std::mt19937::result_type> negative(0, 1);
    std::uniform_int_distribution<std::mt19937::result_type> intDigits(1, theType::integer_decimal_digits);
    std::uniform_int_distribution<std::mt19937::result_type> fracDigits(1, theType::fractional_decimal_digits);
    std::uniform_int_distribution<std::mt19937::result_type> digits(0, 9);
    
    // Generate NUMBER worth of parsable decimal number strings
    std::vector<std::string> values;
    for (uint32_t idx = 0; idx < NUMBER; ++idx)
    {
        std::ostringstream output;
        
        // Decide if the number should be negative
        if (negative(rng) == 1)
        {
            output << "-";
        }
        
        // Generate random integer number digits
        for (uint32_t integerIdx = 0; integerIdx < intDigits(rng); ++integerIdx)
        {
            int digit = digits(rng);
            
            // Integer part cannot start with a zero
            if (integerIdx == 0)
            {
                while (digit == 0)
                {
                    digit = digits(rng);
                }
            }
            
            output << digit;
        }
        
        output << ".";
        
        // Generate random fractional number digits
        uint32_t numFracDigits = fracDigits(rng);
        for (uint32_t fracIdx = 0; fracIdx < numFracDigits; ++fracIdx)
        {
            int digit = digits(rng);
            
            // Fractional part cannot end with a zero
            if (fracIdx == (numFracDigits - 1))
            {
                while (digit == 0)
                {
                    digit = digits(rng);
                }
            }
            
            output << digit;
        }
        
        values.emplace_back(output.str());
        //~ std::cout << "VAL: " << values.back() << std::endl;
    }
    
    // Now validate that the output of the parsed 
    theType fixedValue;
    std::ostringstream output;
    for (auto& value : values)
    {
        fixedValue.parse(value.c_str());
        output << fixedValue;
        
        //~ std::cout << "TEST: " << output.str() << " -- " << value << std::endl;
        BOOST_CHECK(output.str() == value);
        output.str("");
    }
}

BOOST_AUTO_TEST_CASE(t004)
{
    /* TEST CASE 4: Basic test division by unsigned integer
     */ 
    fixed_128_128 val1(18, 55, 0);
    fixed_128_128 val2(0, 1855, 0);
    
    fixed_128_128 answer = val1 / 100;
    BOOST_CHECK(answer == val2);
}

BOOST_AUTO_TEST_CASE(t005)
{
    /* TEST CASE 5: Test parsing a decimal number with a larger than supported
     * fractional part.
     */ 
     
    const char* input = ".101010101010101010100010102030508132134";

    fixed_128_128 value;
#if 0
    value.parse(input);
    
    std::ostringstream output;
    output << value;
    
    BOOST_CHECK(output.str() == "0.0001010203050813213");
#else
    bool exception = false;
    try
    {
        value.parse(input);
    }
    catch (const std::out_of_range& exp)
    {
        exception = true;
    }
    BOOST_CHECK(exception);
#endif
}

BOOST_AUTO_TEST_CASE(t006)
{
    /* TEST CASE 6: zero integer, positive exponent, walking one positive test 
     * cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "0.00000000000000000000000000000000000001e75";
    PARSE_VALUE_CHECK("10000000000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e74";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e73";
    PARSE_VALUE_CHECK("100000000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e72";
    PARSE_VALUE_CHECK("10000000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e71";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e70";
    PARSE_VALUE_CHECK("100000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e69";
    PARSE_VALUE_CHECK("10000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e68";
    PARSE_VALUE_CHECK("1000000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e67";
    PARSE_VALUE_CHECK("100000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e66";
    PARSE_VALUE_CHECK("10000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e65";
    PARSE_VALUE_CHECK("1000000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e64";
    PARSE_VALUE_CHECK("100000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e63";
    PARSE_VALUE_CHECK("10000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e62";
    PARSE_VALUE_CHECK("1000000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e61";
    PARSE_VALUE_CHECK("100000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e60";
    PARSE_VALUE_CHECK("10000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e59";
    PARSE_VALUE_CHECK("1000000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e58";
    PARSE_VALUE_CHECK("100000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e57";
    PARSE_VALUE_CHECK("10000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e56";
    PARSE_VALUE_CHECK("1000000000000000000.0");

    input = "0.00000000000000000000000000000000000001e55";
    PARSE_VALUE_CHECK("100000000000000000.0");

    input = "0.00000000000000000000000000000000000001e54";
    PARSE_VALUE_CHECK("10000000000000000.0");

    input = "0.00000000000000000000000000000000000001e53";
    PARSE_VALUE_CHECK("1000000000000000.0");

    input = "0.00000000000000000000000000000000000001e52";
    PARSE_VALUE_CHECK("100000000000000.0");

    input = "0.00000000000000000000000000000000000001e51";
    PARSE_VALUE_CHECK("10000000000000.0");

    input = "0.00000000000000000000000000000000000001e50";
    PARSE_VALUE_CHECK("1000000000000.0");

    input = "0.00000000000000000000000000000000000001e49";
    PARSE_VALUE_CHECK("100000000000.0");

    input = "0.00000000000000000000000000000000000001e48";
    PARSE_VALUE_CHECK("10000000000.0");

    input = "0.00000000000000000000000000000000000001e47";
    PARSE_VALUE_CHECK("1000000000.0");

    input = "0.00000000000000000000000000000000000001e46";
    PARSE_VALUE_CHECK("100000000.0");

    input = "0.00000000000000000000000000000000000001e45";
    PARSE_VALUE_CHECK("10000000.0");

    input = "0.00000000000000000000000000000000000001e44";
    PARSE_VALUE_CHECK("1000000.0");

    input = "0.00000000000000000000000000000000000001e43";
    PARSE_VALUE_CHECK("100000.0");

    input = "0.00000000000000000000000000000000000001e42";
    PARSE_VALUE_CHECK("10000.0");

    input = "0.00000000000000000000000000000000000001e41";
    PARSE_VALUE_CHECK("1000.0");

    input = "0.00000000000000000000000000000000000001e40";
    PARSE_VALUE_CHECK("100.0");

    input = "0.00000000000000000000000000000000000001e39";
    PARSE_VALUE_CHECK("10.0");

    input = "0.00000000000000000000000000000000000001e38";
    PARSE_VALUE_CHECK("1.0");

    // Cross over
    input = "0.00000000000000000000000000000000000001e37";
    PARSE_VALUE_CHECK("0.1");

    input = "0.00000000000000000000000000000000000001e37";
    PARSE_VALUE_CHECK("0.1");

    input = "0.00000000000000000000000000000000000001e36";
    PARSE_VALUE_CHECK("0.01");

    input = "0.00000000000000000000000000000000000001e35";
    PARSE_VALUE_CHECK("0.001");

    input = "0.00000000000000000000000000000000000001e34";
    PARSE_VALUE_CHECK("0.0001");

    input = "0.00000000000000000000000000000000000001e33";
    PARSE_VALUE_CHECK("0.00001");

    input = "0.00000000000000000000000000000000000001e32";
    PARSE_VALUE_CHECK("0.000001");

    input = "0.00000000000000000000000000000000000001e31";
    PARSE_VALUE_CHECK("0.0000001");

    input = "0.00000000000000000000000000000000000001e30";
    PARSE_VALUE_CHECK("0.00000001");

    input = "0.00000000000000000000000000000000000001e29";
    PARSE_VALUE_CHECK("0.000000001");

    input = "0.00000000000000000000000000000000000001e28";
    PARSE_VALUE_CHECK("0.0000000001");

    input = "0.00000000000000000000000000000000000001e27";
    PARSE_VALUE_CHECK("0.00000000001");

    input = "0.00000000000000000000000000000000000001e26";
    PARSE_VALUE_CHECK("0.000000000001");

    input = "0.00000000000000000000000000000000000001e25";
    PARSE_VALUE_CHECK("0.0000000000001");

    input = "0.00000000000000000000000000000000000001e24";
    PARSE_VALUE_CHECK("0.00000000000001");

    input = "0.00000000000000000000000000000000000001e23";
    PARSE_VALUE_CHECK("0.000000000000001");

    input = "0.00000000000000000000000000000000000001e22";
    PARSE_VALUE_CHECK("0.0000000000000001");

    input = "0.00000000000000000000000000000000000001e21";
    PARSE_VALUE_CHECK("0.00000000000000001");

    input = "0.00000000000000000000000000000000000001e20";
    PARSE_VALUE_CHECK("0.000000000000000001");

    input = "0.00000000000000000000000000000000000001e19";
    PARSE_VALUE_CHECK("0.0000000000000000001");

    input = "0.00000000000000000000000000000000000001e18";
    PARSE_VALUE_CHECK("0.00000000000000000001");

    input = "0.00000000000000000000000000000000000001e17";
    PARSE_VALUE_CHECK("0.000000000000000000001");

    input = "0.00000000000000000000000000000000000001e16";
    PARSE_VALUE_CHECK("0.0000000000000000000001");

    input = "0.00000000000000000000000000000000000001e15";
    PARSE_VALUE_CHECK("0.00000000000000000000001");

    input = "0.00000000000000000000000000000000000001e14";
    PARSE_VALUE_CHECK("0.000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e13";
    PARSE_VALUE_CHECK("0.0000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e12";
    PARSE_VALUE_CHECK("0.00000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e11";
    PARSE_VALUE_CHECK("0.000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e10";
    PARSE_VALUE_CHECK("0.0000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e9";
    PARSE_VALUE_CHECK("0.00000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e8";
    PARSE_VALUE_CHECK("0.000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e7";
    PARSE_VALUE_CHECK("0.0000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e6";
    PARSE_VALUE_CHECK("0.00000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e5";
    PARSE_VALUE_CHECK("0.000000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e4";
    PARSE_VALUE_CHECK("0.0000000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e3";
    PARSE_VALUE_CHECK("0.00000000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e2";
    PARSE_VALUE_CHECK("0.000000000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e1";
    PARSE_VALUE_CHECK("0.0000000000000000000000000000000000001");

    input = "0.00000000000000000000000000000000000001e0";
    PARSE_VALUE_CHECK("0.00000000000000000000000000000000000001");
}

BOOST_AUTO_TEST_CASE(t007)
{
    /* TEST CASE 7: non-zero integer, positive exponent, walking value 
     * positive+negative test cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "1.00000000000000000000000000000000000001e1";
    PARSE_VALUE_CHECK("10.0000000000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e2";
    PARSE_VALUE_CHECK("100.000000000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e3";
    PARSE_VALUE_CHECK("1000.00000000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e4";
    PARSE_VALUE_CHECK("10000.0000000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e5";
    PARSE_VALUE_CHECK("100000.000000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e6";
    PARSE_VALUE_CHECK("1000000.00000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e7";
    PARSE_VALUE_CHECK("10000000.0000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e8";
    PARSE_VALUE_CHECK("100000000.000000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e9";
    PARSE_VALUE_CHECK("1000000000.00000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e10";
    PARSE_VALUE_CHECK("10000000000.0000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e11";
    PARSE_VALUE_CHECK("100000000000.000000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e12";
    PARSE_VALUE_CHECK("1000000000000.00000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e13";
    PARSE_VALUE_CHECK("10000000000000.0000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e14";
    PARSE_VALUE_CHECK("100000000000000.000000000000000000000001");

    input = "1.00000000000000000000000000000000000001e15";
    PARSE_VALUE_CHECK("1000000000000000.00000000000000000000001");

    input = "1.00000000000000000000000000000000000001e16";
    PARSE_VALUE_CHECK("10000000000000000.0000000000000000000001");

    input = "1.00000000000000000000000000000000000001e17";
    PARSE_VALUE_CHECK("100000000000000000.000000000000000000001");

    input = "1.00000000000000000000000000000000000001e18";
    PARSE_VALUE_CHECK("1000000000000000000.00000000000000000001");

    input = "1.00000000000000000000000000000000000001e19";
    PARSE_VALUE_CHECK("10000000000000000000.0000000000000000001");

    input = "1.00000000000000000000000000000000000001e20";
    PARSE_VALUE_CHECK("100000000000000000000.000000000000000001");

    input = "1.00000000000000000000000000000000000001e21";
    PARSE_VALUE_CHECK("1000000000000000000000.00000000000000001");

    input = "1.00000000000000000000000000000000000001e22";
    PARSE_VALUE_CHECK("10000000000000000000000.0000000000000001");

    input = "1.00000000000000000000000000000000000001e23";
    PARSE_VALUE_CHECK("100000000000000000000000.000000000000001");

    input = "1.00000000000000000000000000000000000001e24";
    PARSE_VALUE_CHECK("1000000000000000000000000.00000000000001");

    input = "1.00000000000000000000000000000000000001e25";
    PARSE_VALUE_CHECK("10000000000000000000000000.0000000000001");

    input = "1.00000000000000000000000000000000000001e26";
    PARSE_VALUE_CHECK("100000000000000000000000000.000000000001");

    input = "1.00000000000000000000000000000000000001e27";
    PARSE_VALUE_CHECK("1000000000000000000000000000.00000000001");

    input = "1.00000000000000000000000000000000000001e28";
    PARSE_VALUE_CHECK("10000000000000000000000000000.0000000001");

    input = "1.00000000000000000000000000000000000001e29";
    PARSE_VALUE_CHECK("100000000000000000000000000000.000000001");

    input = "1.00000000000000000000000000000000000001e30";
    PARSE_VALUE_CHECK("1000000000000000000000000000000.00000001");

    input = "1.00000000000000000000000000000000000001e31";
    PARSE_VALUE_CHECK("10000000000000000000000000000000.0000001");

    input = "1.00000000000000000000000000000000000001e32";
    PARSE_VALUE_CHECK("100000000000000000000000000000000.000001");

    input = "1.00000000000000000000000000000000000001e33";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000.00001");

    input = "1.00000000000000000000000000000000000001e34";
    PARSE_VALUE_CHECK("10000000000000000000000000000000000.0001");

    input = "1.00000000000000000000000000000000000001e35";
    PARSE_VALUE_CHECK("100000000000000000000000000000000000.001");

    input = "1.00000000000000000000000000000000000001e36";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000000.01");

    input = "1.00000000000000000000000000000000000001e37";
    PARSE_VALUE_CHECK("10000000000000000000000000000000000000.1");

    input = "1.00000000000000000000000000000000000001e38";
    bool exception = false;
    PARSE_EXCEPTION_CHECK
}

BOOST_AUTO_TEST_CASE(t008)
{
    /* TEST CASE 8: zero integer, positive exponent, walking one negative test 
     * cases
     */ 
    fixed_64_64 value;
    std::ostringstream output;
     
    const char* input = "0.00000000000000000000000000000000000001e76";
    bool exception = false;
    PARSE_EXCEPTION_CHECK
    
    input = "0.0000000000000000000000000000000000001e75";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000000000000001e74";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000000000001e73";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000000000001e72";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000000000001e71";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000000001e70";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000000001e69";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000000001e68";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000001e67";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000001e66";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000001e65";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000001e64";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000001e63";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000001e62";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000001e61";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000001e60";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000001e59";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000001e58";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000001e57";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000001e56";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000001e55";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000001e54";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000001e53";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000001e52";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000001e51";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000001e50";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000001e49";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000001e48";
    PARSE_EXCEPTION_CHECK

    input = "0.000000001e47";
    PARSE_EXCEPTION_CHECK

    input = "0.00000001e46";
    PARSE_EXCEPTION_CHECK

    input = "0.0000001e45";
    PARSE_EXCEPTION_CHECK

    input = "0.000001e44";
    PARSE_EXCEPTION_CHECK

    input = "0.00001e43";
    PARSE_EXCEPTION_CHECK

    input = "0.0001e42";
    PARSE_EXCEPTION_CHECK

    input = "0.001e41";
    PARSE_EXCEPTION_CHECK

    input = "0.01e40";
    PARSE_EXCEPTION_CHECK

    input = "0.1e39";
    PARSE_EXCEPTION_CHECK

    // Cross over
    input = "1.0e38";
    PARSE_EXCEPTION_CHECK

    input = "10.0e37";
    PARSE_EXCEPTION_CHECK

    input = "100.0e36";
    PARSE_EXCEPTION_CHECK

    input = "1000.0e35";
    PARSE_EXCEPTION_CHECK

    input = "10000.0e34";
    PARSE_EXCEPTION_CHECK

    input = "100000.0e33";
    PARSE_EXCEPTION_CHECK

    input = "1000000.0e32";
    PARSE_EXCEPTION_CHECK

    input = "10000000.0e31";
    PARSE_EXCEPTION_CHECK

    input = "100000000.0e30";
    PARSE_EXCEPTION_CHECK

    input = "1000000000.0e29";
    PARSE_EXCEPTION_CHECK

    input = "10000000000.0e28";
    PARSE_EXCEPTION_CHECK

    input = "100000000000.0e27";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000.0e26";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000.0e25";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000.0e24";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000.0e23";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000.0e22";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000.0e21";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000.0e20";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000.0e19";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000.0e18";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000.0e17";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000.0e16";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000.0e15";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000.0e14";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000.0e13";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000.0e12";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000.0e11";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000.0e10";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000000.0e9";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000000.0e8";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000000.0e7";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000000000.0e6";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000000000.0e5";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000000000.0e4";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000000000000.0e3";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000000000000.0e2";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000000000000.0e1";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000000000000.0e0";
    PARSE_EXCEPTION_CHECK
}

BOOST_AUTO_TEST_CASE(t009)
{
    /* TEST CASE 9: zero factional, negative exponent, walking one positive test 
     * cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "10000000000000000000000000000000000000.0e-1";
    PARSE_VALUE_CHECK(  "1000000000000000000000000000000000000.0");
    
    input = "10000000000000000000000000000000000000.0e-2";
    PARSE_VALUE_CHECK("100000000000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-3";
    PARSE_VALUE_CHECK("10000000000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-4";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-5";
    PARSE_VALUE_CHECK("100000000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-6";
    PARSE_VALUE_CHECK("10000000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-7";
    PARSE_VALUE_CHECK("1000000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-8";
    PARSE_VALUE_CHECK("100000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-9";
    PARSE_VALUE_CHECK("10000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-10";
    PARSE_VALUE_CHECK("1000000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-11";
    PARSE_VALUE_CHECK("100000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-12";
    PARSE_VALUE_CHECK("10000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-13";
    PARSE_VALUE_CHECK("1000000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-14";
    PARSE_VALUE_CHECK("100000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-15";
    PARSE_VALUE_CHECK("10000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-16";
    PARSE_VALUE_CHECK("1000000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-17";
    PARSE_VALUE_CHECK("100000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-18";
    PARSE_VALUE_CHECK("10000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-19";
    PARSE_VALUE_CHECK("1000000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-20";
    PARSE_VALUE_CHECK("100000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-21";
    PARSE_VALUE_CHECK("10000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-22";
    PARSE_VALUE_CHECK("1000000000000000.0");

    input = "10000000000000000000000000000000000000.0e-23";
    PARSE_VALUE_CHECK("100000000000000.0");

    input = "10000000000000000000000000000000000000.0e-24";
    PARSE_VALUE_CHECK("10000000000000.0");

    input = "10000000000000000000000000000000000000.0e-25";
    PARSE_VALUE_CHECK("1000000000000.0");

    input = "10000000000000000000000000000000000000.0e-26";
    PARSE_VALUE_CHECK("100000000000.0");

    input = "10000000000000000000000000000000000000.0e-27";
    PARSE_VALUE_CHECK("10000000000.0");

    input = "10000000000000000000000000000000000000.0e-28";
    PARSE_VALUE_CHECK("1000000000.0");

    input = "10000000000000000000000000000000000000.0e-29";
    PARSE_VALUE_CHECK("100000000.0");

    input = "10000000000000000000000000000000000000.0e-30";
    PARSE_VALUE_CHECK("10000000.0");

    input = "10000000000000000000000000000000000000.0e-31";
    PARSE_VALUE_CHECK("1000000.0");

    input = "10000000000000000000000000000000000000.0e-32";
    PARSE_VALUE_CHECK("100000.0");

    input = "10000000000000000000000000000000000000.0e-33";
    PARSE_VALUE_CHECK("10000.0");

    input = "10000000000000000000000000000000000000.0e-34";
    PARSE_VALUE_CHECK("1000.0");

    input = "10000000000000000000000000000000000000.0e-35";
    PARSE_VALUE_CHECK("100.0");

    input = "10000000000000000000000000000000000000.0e-36";
    PARSE_VALUE_CHECK("10.0");

    input = "10000000000000000000000000000000000000.0e-37";
    PARSE_VALUE_CHECK("1.0");
    
    // Cross over
    input = "10000000000000000000000000000000000000.0e-38";
    PARSE_VALUE_CHECK("0.1");

    input = "10000000000000000000000000000000000000.0e-39";
    PARSE_VALUE_CHECK("0.01");

    input = "10000000000000000000000000000000000000.0e-40";
    PARSE_VALUE_CHECK("0.001");

    input = "10000000000000000000000000000000000000.0e-41";
    PARSE_VALUE_CHECK("0.0001");

    input = "10000000000000000000000000000000000000.0e-42";
    PARSE_VALUE_CHECK("0.00001");

    input = "10000000000000000000000000000000000000.0e-43";
    PARSE_VALUE_CHECK("0.000001");

    input = "10000000000000000000000000000000000000.0e-44";
    PARSE_VALUE_CHECK("0.0000001");

    input = "10000000000000000000000000000000000000.0e-45";
    PARSE_VALUE_CHECK("0.00000001");

    input = "10000000000000000000000000000000000000.0e-46";
    PARSE_VALUE_CHECK("0.000000001");

    input = "10000000000000000000000000000000000000.0e-47";
    PARSE_VALUE_CHECK("0.0000000001");

    input = "10000000000000000000000000000000000000.0e-48";
    PARSE_VALUE_CHECK("0.00000000001");

    input = "10000000000000000000000000000000000000.0e-49";
    PARSE_VALUE_CHECK("0.000000000001");

    input = "10000000000000000000000000000000000000.0e-50";
    PARSE_VALUE_CHECK("0.0000000000001");

    input = "10000000000000000000000000000000000000.0e-51";
    PARSE_VALUE_CHECK("0.00000000000001");

    input = "10000000000000000000000000000000000000.0e-52";
    PARSE_VALUE_CHECK("0.000000000000001");

    input = "10000000000000000000000000000000000000.0e-53";
    PARSE_VALUE_CHECK("0.0000000000000001");

    input = "10000000000000000000000000000000000000.0e-54";
    PARSE_VALUE_CHECK("0.00000000000000001");

    input = "10000000000000000000000000000000000000.0e-55";
    PARSE_VALUE_CHECK("0.000000000000000001");

    input = "10000000000000000000000000000000000000.0e-56";
    PARSE_VALUE_CHECK("0.0000000000000000001");

    input = "10000000000000000000000000000000000000.0e-57";
    PARSE_VALUE_CHECK("0.00000000000000000001");

    input = "10000000000000000000000000000000000000.0e-58";
    PARSE_VALUE_CHECK("0.000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-59";
    PARSE_VALUE_CHECK("0.0000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-60";
    PARSE_VALUE_CHECK("0.00000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-61";
    PARSE_VALUE_CHECK("0.000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-62";
    PARSE_VALUE_CHECK("0.0000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-63";
    PARSE_VALUE_CHECK("0.00000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-64";
    PARSE_VALUE_CHECK("0.000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-65";
    PARSE_VALUE_CHECK("0.0000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-66";
    PARSE_VALUE_CHECK("0.00000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-67";
    PARSE_VALUE_CHECK("0.000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-68";
    PARSE_VALUE_CHECK("0.0000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-69";
    PARSE_VALUE_CHECK("0.00000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-70";
    PARSE_VALUE_CHECK("0.000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-71";
    PARSE_VALUE_CHECK("0.0000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-72";
    PARSE_VALUE_CHECK("0.00000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-73";
    PARSE_VALUE_CHECK("0.000000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-74";
    PARSE_VALUE_CHECK("0.0000000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.0e-75";
    PARSE_VALUE_CHECK("0.00000000000000000000000000000000000001");
}

BOOST_AUTO_TEST_CASE(t010)
{
    /* TEST CASE 10: non-zero factional, negative exponent, walking value 
     * positive+negative test cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "10000000000000000000000000000000000000.1e-1";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000000.01");

    input = "10000000000000000000000000000000000000.1e-2";
    PARSE_VALUE_CHECK("100000000000000000000000000000000000.001");

    input = "10000000000000000000000000000000000000.1e-3";
    PARSE_VALUE_CHECK("10000000000000000000000000000000000.0001");

    input = "10000000000000000000000000000000000000.1e-4";
    PARSE_VALUE_CHECK("1000000000000000000000000000000000.00001");

    input = "10000000000000000000000000000000000000.1e-5";
    PARSE_VALUE_CHECK("100000000000000000000000000000000.000001");

    input = "10000000000000000000000000000000000000.1e-6";
    PARSE_VALUE_CHECK("10000000000000000000000000000000.0000001");

    input = "10000000000000000000000000000000000000.1e-7";
    PARSE_VALUE_CHECK("1000000000000000000000000000000.00000001");

    input = "10000000000000000000000000000000000000.1e-8";
    PARSE_VALUE_CHECK("100000000000000000000000000000.000000001");

    input = "10000000000000000000000000000000000000.1e-9";
    PARSE_VALUE_CHECK("10000000000000000000000000000.0000000001");

    input = "10000000000000000000000000000000000000.1e-10";
    PARSE_VALUE_CHECK("1000000000000000000000000000.00000000001");

    input = "10000000000000000000000000000000000000.1e-11";
    PARSE_VALUE_CHECK("100000000000000000000000000.000000000001");

    input = "10000000000000000000000000000000000000.1e-12";
    PARSE_VALUE_CHECK("10000000000000000000000000.0000000000001");

    input = "10000000000000000000000000000000000000.1e-13";
    PARSE_VALUE_CHECK("1000000000000000000000000.00000000000001");

    input = "10000000000000000000000000000000000000.1e-14";
    PARSE_VALUE_CHECK("100000000000000000000000.000000000000001");

    input = "10000000000000000000000000000000000000.1e-15";
    PARSE_VALUE_CHECK("10000000000000000000000.0000000000000001");

    input = "10000000000000000000000000000000000000.1e-16";
    PARSE_VALUE_CHECK("1000000000000000000000.00000000000000001");

    input = "10000000000000000000000000000000000000.1e-17";
    PARSE_VALUE_CHECK("100000000000000000000.000000000000000001");

    input = "10000000000000000000000000000000000000.1e-18";
    PARSE_VALUE_CHECK("10000000000000000000.0000000000000000001");

    input = "10000000000000000000000000000000000000.1e-19";
    PARSE_VALUE_CHECK("1000000000000000000.00000000000000000001");

    input = "10000000000000000000000000000000000000.1e-20";
    PARSE_VALUE_CHECK("100000000000000000.000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-21";
    PARSE_VALUE_CHECK("10000000000000000.0000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-22";
    PARSE_VALUE_CHECK("1000000000000000.00000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-23";
    PARSE_VALUE_CHECK("100000000000000.000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-24";
    PARSE_VALUE_CHECK("10000000000000.0000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-25";
    PARSE_VALUE_CHECK("1000000000000.00000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-26";
    PARSE_VALUE_CHECK("100000000000.000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-27";
    PARSE_VALUE_CHECK("10000000000.0000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-28";
    PARSE_VALUE_CHECK("1000000000.00000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-29";
    PARSE_VALUE_CHECK("100000000.000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-30";
    PARSE_VALUE_CHECK("10000000.0000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-31";
    PARSE_VALUE_CHECK("1000000.00000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-32";
    PARSE_VALUE_CHECK("100000.000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-33";
    PARSE_VALUE_CHECK("10000.0000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-34";
    PARSE_VALUE_CHECK("1000.00000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-35";
    PARSE_VALUE_CHECK("100.000000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-36";
    PARSE_VALUE_CHECK("10.0000000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-37";
    PARSE_VALUE_CHECK("1.00000000000000000000000000000000000001");

    input = "10000000000000000000000000000000000000.1e-38";
    bool exception = false;
    PARSE_EXCEPTION_CHECK
}

BOOST_AUTO_TEST_CASE(t011)
{
    /* TEST CASE 11: zero factional, negative exponent, walking one negative test 
     * cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "10000000000000000000000000000000000000.0e-76";
    bool exception = false;
    PARSE_EXCEPTION_CHECK
    
    input = "1000000000000000000000000000000000000.0e-75";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000000000000.0e-74";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000000000.0e-73";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000000000.0e-72";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000000000.0e-71";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000000.0e-70";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000000.0e-69";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000000.0e-68";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000000.0e-67";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000000.0e-66";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000000.0e-65";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000000.0e-64";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000000.0e-63";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000000.0e-62";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000000.0e-61";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000000.0e-60";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000000.0e-59";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000000.0e-58";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000000.0e-57";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000000.0e-56";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000000.0e-55";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000000.0e-54";
    PARSE_EXCEPTION_CHECK

    input = "100000000000000.0e-53";
    PARSE_EXCEPTION_CHECK

    input = "10000000000000.0e-52";
    PARSE_EXCEPTION_CHECK

    input = "1000000000000.0e-51";
    PARSE_EXCEPTION_CHECK

    input = "100000000000.0e-50";
    PARSE_EXCEPTION_CHECK

    input = "10000000000.0e-49";
    PARSE_EXCEPTION_CHECK

    input = "1000000000.0e-48";
    PARSE_EXCEPTION_CHECK

    input = "100000000.0e-47";
    PARSE_EXCEPTION_CHECK

    input = "10000000.0e-46";
    PARSE_EXCEPTION_CHECK

    input = "1000000.0e-45";
    PARSE_EXCEPTION_CHECK

    input = "100000.0e-44";
    PARSE_EXCEPTION_CHECK

    input = "10000.0e-43";
    PARSE_EXCEPTION_CHECK

    input = "1000.0e-42";
    PARSE_EXCEPTION_CHECK

    input = "100.0e-41";
    PARSE_EXCEPTION_CHECK

    input = "10.0e-40";
    PARSE_EXCEPTION_CHECK

    input = "1.0e-39";
    PARSE_EXCEPTION_CHECK

    // Cross over
    input = "0.1e-38";
    PARSE_EXCEPTION_CHECK

    input = "0.01e-37";
    PARSE_EXCEPTION_CHECK

    input = "0.001e-36";
    PARSE_EXCEPTION_CHECK

    input = "0.0001e-35";
    PARSE_EXCEPTION_CHECK

    input = "0.00001e-34";
    PARSE_EXCEPTION_CHECK

    input = "0.000001e-33";
    PARSE_EXCEPTION_CHECK

    input = "0.0000001e-32";
    PARSE_EXCEPTION_CHECK

    input = "0.00000001e-31";
    PARSE_EXCEPTION_CHECK

    input = "0.000000001e-30";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000001e-29";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000001e-28";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000001e-27";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000001e-26";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000001e-25";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000001e-24";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000001e-23";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000001e-22";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000001e-21";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000001e-20";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000001e-19";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000001e-18";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000001e-17";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000001e-16";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000001e-15";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000001e-14";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000001e-13";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000001e-12";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000001e-11";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000001e-10";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000000001e-9";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000000001e-8";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000000001e-7";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000000000001e-6";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000000000001e-5";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000000000001e-4";
    PARSE_EXCEPTION_CHECK

    input = "0.000000000000000000000000000000000001e-3";
    PARSE_EXCEPTION_CHECK

    input = "0.0000000000000000000000000000000000001e-2";
    PARSE_EXCEPTION_CHECK

    input = "0.00000000000000000000000000000000000001e-1";
    PARSE_EXCEPTION_CHECK
}

BOOST_AUTO_TEST_CASE(t012)
{
    /* TEST CASE 12: non-zero negative integer, positive exponent, walking value 
     * positive+negative test cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "-1.00000000000000000000000000000000000001e1";
    PARSE_VALUE_CHECK("-10.0000000000000000000000000000000000001");
    
    input = "-1.00000000000000000000000000000000000001e2";
    PARSE_VALUE_CHECK("-100.000000000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e3";
    PARSE_VALUE_CHECK("-1000.00000000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e4";
    PARSE_VALUE_CHECK("-10000.0000000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e5";
    PARSE_VALUE_CHECK("-100000.000000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e6";
    PARSE_VALUE_CHECK("-1000000.00000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e7";
    PARSE_VALUE_CHECK("-10000000.0000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e8";
    PARSE_VALUE_CHECK("-100000000.000000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e9";
    PARSE_VALUE_CHECK("-1000000000.00000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e10";
    PARSE_VALUE_CHECK("-10000000000.0000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e11";
    PARSE_VALUE_CHECK("-100000000000.000000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e12";
    PARSE_VALUE_CHECK("-1000000000000.00000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e13";
    PARSE_VALUE_CHECK("-10000000000000.0000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e14";
    PARSE_VALUE_CHECK("-100000000000000.000000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e15";
    PARSE_VALUE_CHECK("-1000000000000000.00000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e16";
    PARSE_VALUE_CHECK("-10000000000000000.0000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e17";
    PARSE_VALUE_CHECK("-100000000000000000.000000000000000000001");

    input = "-1.00000000000000000000000000000000000001e18";
    PARSE_VALUE_CHECK("-1000000000000000000.00000000000000000001");

    input = "-1.00000000000000000000000000000000000001e19";
    PARSE_VALUE_CHECK("-10000000000000000000.0000000000000000001");

    input = "-1.00000000000000000000000000000000000001e20";
    PARSE_VALUE_CHECK("-100000000000000000000.000000000000000001");

    input = "-1.00000000000000000000000000000000000001e21";
    PARSE_VALUE_CHECK("-1000000000000000000000.00000000000000001");

    input = "-1.00000000000000000000000000000000000001e22";
    PARSE_VALUE_CHECK("-10000000000000000000000.0000000000000001");

    input = "-1.00000000000000000000000000000000000001e23";
    PARSE_VALUE_CHECK("-100000000000000000000000.000000000000001");

    input = "-1.00000000000000000000000000000000000001e24";
    PARSE_VALUE_CHECK("-1000000000000000000000000.00000000000001");

    input = "-1.00000000000000000000000000000000000001e25";
    PARSE_VALUE_CHECK("-10000000000000000000000000.0000000000001");

    input = "-1.00000000000000000000000000000000000001e26";
    PARSE_VALUE_CHECK("-100000000000000000000000000.000000000001");

    input = "-1.00000000000000000000000000000000000001e27";
    PARSE_VALUE_CHECK("-1000000000000000000000000000.00000000001");

    input = "-1.00000000000000000000000000000000000001e28";
    PARSE_VALUE_CHECK("-10000000000000000000000000000.0000000001");

    input = "-1.00000000000000000000000000000000000001e29";
    PARSE_VALUE_CHECK("-100000000000000000000000000000.000000001");

    input = "-1.00000000000000000000000000000000000001e30";
    PARSE_VALUE_CHECK("-1000000000000000000000000000000.00000001");

    input = "-1.00000000000000000000000000000000000001e31";
    PARSE_VALUE_CHECK("-10000000000000000000000000000000.0000001");

    input = "-1.00000000000000000000000000000000000001e32";
    PARSE_VALUE_CHECK("-100000000000000000000000000000000.000001");

    input = "-1.00000000000000000000000000000000000001e33";
    PARSE_VALUE_CHECK("-1000000000000000000000000000000000.00001");

    input = "-1.00000000000000000000000000000000000001e34";
    PARSE_VALUE_CHECK("-10000000000000000000000000000000000.0001");

    input = "-1.00000000000000000000000000000000000001e35";
    PARSE_VALUE_CHECK("-100000000000000000000000000000000000.001");

    input = "-1.00000000000000000000000000000000000001e36";
    PARSE_VALUE_CHECK("-1000000000000000000000000000000000000.01");

    input = "-1.00000000000000000000000000000000000001e37";
    PARSE_VALUE_CHECK("-10000000000000000000000000000000000000.1");

    input = "-1.00000000000000000000000000000000000001e38";
    bool exception = false;
    PARSE_EXCEPTION_CHECK
}

BOOST_AUTO_TEST_CASE(t013)
{
    /* TEST CASE 13: non-zero negative factional, negative exponent, walking
     * value positive+negative test cases
     */ 
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "-10000000000000000000000000000000000000.1e-1";
    PARSE_VALUE_CHECK("-1000000000000000000000000000000000000.01");

    input = "-10000000000000000000000000000000000000.1e-2";
    PARSE_VALUE_CHECK("-100000000000000000000000000000000000.001");

    input = "-10000000000000000000000000000000000000.1e-3";
    PARSE_VALUE_CHECK("-10000000000000000000000000000000000.0001");

    input = "-10000000000000000000000000000000000000.1e-4";
    PARSE_VALUE_CHECK("-1000000000000000000000000000000000.00001");

    input = "-10000000000000000000000000000000000000.1e-5";
    PARSE_VALUE_CHECK("-100000000000000000000000000000000.000001");

    input = "-10000000000000000000000000000000000000.1e-6";
    PARSE_VALUE_CHECK("-10000000000000000000000000000000.0000001");

    input = "-10000000000000000000000000000000000000.1e-7";
    PARSE_VALUE_CHECK("-1000000000000000000000000000000.00000001");

    input = "-10000000000000000000000000000000000000.1e-8";
    PARSE_VALUE_CHECK("-100000000000000000000000000000.000000001");

    input = "-10000000000000000000000000000000000000.1e-9";
    PARSE_VALUE_CHECK("-10000000000000000000000000000.0000000001");

    input = "-10000000000000000000000000000000000000.1e-10";
    PARSE_VALUE_CHECK("-1000000000000000000000000000.00000000001");

    input = "-10000000000000000000000000000000000000.1e-11";
    PARSE_VALUE_CHECK("-100000000000000000000000000.000000000001");

    input = "-10000000000000000000000000000000000000.1e-12";
    PARSE_VALUE_CHECK("-10000000000000000000000000.0000000000001");

    input = "-10000000000000000000000000000000000000.1e-13";
    PARSE_VALUE_CHECK("-1000000000000000000000000.00000000000001");

    input = "-10000000000000000000000000000000000000.1e-14";
    PARSE_VALUE_CHECK("-100000000000000000000000.000000000000001");

    input = "-10000000000000000000000000000000000000.1e-15";
    PARSE_VALUE_CHECK("-10000000000000000000000.0000000000000001");

    input = "-10000000000000000000000000000000000000.1e-16";
    PARSE_VALUE_CHECK("-1000000000000000000000.00000000000000001");

    input = "-10000000000000000000000000000000000000.1e-17";
    PARSE_VALUE_CHECK("-100000000000000000000.000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-18";
    PARSE_VALUE_CHECK("-10000000000000000000.0000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-19";
    PARSE_VALUE_CHECK("-1000000000000000000.00000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-20";
    PARSE_VALUE_CHECK("-100000000000000000.000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-21";
    PARSE_VALUE_CHECK("-10000000000000000.0000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-22";
    PARSE_VALUE_CHECK("-1000000000000000.00000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-23";
    PARSE_VALUE_CHECK("-100000000000000.000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-24";
    PARSE_VALUE_CHECK("-10000000000000.0000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-25";
    PARSE_VALUE_CHECK("-1000000000000.00000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-26";
    PARSE_VALUE_CHECK("-100000000000.000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-27";
    PARSE_VALUE_CHECK("-10000000000.0000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-28";
    PARSE_VALUE_CHECK("-1000000000.00000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-29";
    PARSE_VALUE_CHECK("-100000000.000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-30";
    PARSE_VALUE_CHECK("-10000000.0000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-31";
    PARSE_VALUE_CHECK("-1000000.00000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-32";
    PARSE_VALUE_CHECK("-100000.000000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-33";
    PARSE_VALUE_CHECK("-10000.0000000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-34";
    PARSE_VALUE_CHECK("-1000.00000000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-35";
    PARSE_VALUE_CHECK("-100.000000000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-36";
    PARSE_VALUE_CHECK("-10.0000000000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-37";
    PARSE_VALUE_CHECK("-1.00000000000000000000000000000000000001");

    input = "-10000000000000000000000000000000000000.1e-38";
    bool exception = false;
    PARSE_EXCEPTION_CHECK
}

BOOST_AUTO_TEST_CASE(t014)
{
    /* TEST CASE 14: LEADING_ZERO=true; negative zero parse
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "-0.9";
    PARSE_VALUE_CHECK("-0.9");

    input = "-0.99";
    PARSE_VALUE_CHECK("-0.99");

    input = "-0.999";
    PARSE_VALUE_CHECK("-0.999");

    input = "-0.9999";
    PARSE_VALUE_CHECK("-0.9999");

    input = "-0.99999";
    PARSE_VALUE_CHECK("-0.99999");

    input = "-0.999999";
    PARSE_VALUE_CHECK("-0.999999");

    input = "-0.9999999";
    PARSE_VALUE_CHECK("-0.9999999");

    input = "-0.99999999";
    PARSE_VALUE_CHECK("-0.99999999");

    input = "-0.999999999";
    PARSE_VALUE_CHECK("-0.999999999");

    input = "-0.9999999999";
    PARSE_VALUE_CHECK("-0.9999999999");

    input = "-0.99999999999";
    PARSE_VALUE_CHECK("-0.99999999999");

    input = "-0.999999999999";
    PARSE_VALUE_CHECK("-0.999999999999");

    input = "-0.9999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999");

    input = "-0.99999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999");

    input = "-0.999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999");

    input = "-0.9999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999");

    input = "-0.99999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999");

    input = "-0.999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999");

    input = "-0.9999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999");

    input = "-0.99999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999");

    input = "-0.999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999");

    input = "-0.9999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999");

    input = "-0.99999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999");

    input = "-0.999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999");

    input = "-0.9999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999");

    input = "-0.99999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999");

    input = "-0.999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999");

    input = "-0.9999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999");

    input = "-0.99999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999");

    input = "-0.999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999999");

    input = "-0.9999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999999");

    input = "-0.99999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999999");

    input = "-0.999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999999999");

    input = "-0.9999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999999999");

    input = "-0.99999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999999999");

    input = "-0.999999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999999999999");

    input = "-0.9999999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999999999999");

    input = "-0.99999999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999999999999");
}

BOOST_AUTO_TEST_CASE(t015)
{
    /* TEST CASE 15: LEADING_ZERO=false; negative zero parse
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "-.9";
    PARSE_VALUE_CHECK("-0.9");

    input = "-.99";
    PARSE_VALUE_CHECK("-0.99");

    input = "-.999";
    PARSE_VALUE_CHECK("-0.999");

    input = "-.9999";
    PARSE_VALUE_CHECK("-0.9999");

    input = "-.99999";
    PARSE_VALUE_CHECK("-0.99999");

    input = "-.999999";
    PARSE_VALUE_CHECK("-0.999999");

    input = "-.9999999";
    PARSE_VALUE_CHECK("-0.9999999");

    input = "-.99999999";
    PARSE_VALUE_CHECK("-0.99999999");

    input = "-.999999999";
    PARSE_VALUE_CHECK("-0.999999999");

    input = "-.9999999999";
    PARSE_VALUE_CHECK("-0.9999999999");

    input = "-.99999999999";
    PARSE_VALUE_CHECK("-0.99999999999");

    input = "-.999999999999";
    PARSE_VALUE_CHECK("-0.999999999999");

    input = "-.9999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999");

    input = "-.99999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999");

    input = "-.999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999");

    input = "-.9999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999");

    input = "-.99999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999");

    input = "-.999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999");

    input = "-.9999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999");

    input = "-.99999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999");

    input = "-.999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999");

    input = "-.9999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999");

    input = "-.99999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999");

    input = "-.999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999");

    input = "-.9999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999");

    input = "-.99999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999");

    input = "-.999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999");

    input = "-.9999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999");

    input = "-.99999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999");

    input = "-.999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999999");

    input = "-.9999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999999");

    input = "-.99999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999999");

    input = "-.999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999999999");

    input = "-.9999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999999999");

    input = "-.99999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999999999");

    input = "-.999999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.999999999999999999999999999999999999");

    input = "-.9999999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.9999999999999999999999999999999999999");

    input = "-.99999999999999999999999999999999999999";
    PARSE_VALUE_CHECK("-0.99999999999999999999999999999999999999");
}

BOOST_AUTO_TEST_CASE(t016)
{
    /* TEST CASE 16: negative zero comparison
     */ 
    fixed_128_128 val1;
    val1.parse("-0.9");
    
    fixed_128_128 val2;
    val2.parse("-0.9");
    
    //             -0.9 OP -0.9
    BOOST_CHECK(  (val1 == val2));
    BOOST_CHECK(! (val1 != val2));
    BOOST_CHECK(! (val1 > val2));
    BOOST_CHECK(! (val1 < val2));
    BOOST_CHECK(  (val1 >= val2));
    BOOST_CHECK(  (val1 <= val2));
    
    // 0.9
    val2.assignUnscaledFrac(0, 9, 0);
    
    //             -0.9 OP 0.9
    BOOST_CHECK(! (val1 == val2));
    BOOST_CHECK(  (val1 != val2));
    BOOST_CHECK(! (val1 > val2));
    BOOST_CHECK(  (val1 < val2));
    BOOST_CHECK(! (val1 >= val2));
    BOOST_CHECK(  (val1 <= val2));
}

BOOST_AUTO_TEST_CASE(t017)
{
    /* TEST CASE 17: positive divide by positive integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "90000000000000000000000000000000000000.0";
    value.parse(input);
    value = value / 1;
    VALUE_CHECK("90000000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000000.0");

    value = value / 10;
    VALUE_CHECK("90000000000.0");

    value = value / 10;
    VALUE_CHECK("9000000000.0");

    value = value / 10;
    VALUE_CHECK("900000000.0");

    value = value / 10;
    VALUE_CHECK("90000000.0");

    value = value / 10;
    VALUE_CHECK("9000000.0");

    value = value / 10;
    VALUE_CHECK("900000.0");

    value = value / 10;
    VALUE_CHECK("90000.0");

    value = value / 10;
    VALUE_CHECK("9000.0");

    value = value / 10;
    VALUE_CHECK("900.0");

    value = value / 10;
    VALUE_CHECK("90.0");

    value = value / 10;
    VALUE_CHECK("9.0");

    // Cross over
    value = value / 10;
    VALUE_CHECK("0.9");

    value = value / 10;
    VALUE_CHECK("0.09");

    value = value / 10;
    VALUE_CHECK("0.009");

    value = value / 10;
    VALUE_CHECK("0.0009");

    value = value / 10;
    VALUE_CHECK("0.00009");

    value = value / 10;
    VALUE_CHECK("0.000009");

    value = value / 10;
    VALUE_CHECK("0.0000009");

    value = value / 10;
    VALUE_CHECK("0.00000009");

    value = value / 10;
    VALUE_CHECK("0.000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.000000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.0000000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("0.00000000000000000000000000000000000009");
}

BOOST_AUTO_TEST_CASE(t018)
{
    /* TEST CASE 18: negative divide by positive integer
     */ 
    
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "-90000000000000000000000000000000000000.0";
    value.parse(input);
    value = value / 1;
    VALUE_CHECK("-90000000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000000.0");

    value = value / 10;
    VALUE_CHECK("-900000000.0");

    value = value / 10;
    VALUE_CHECK("-90000000.0");

    value = value / 10;
    VALUE_CHECK("-9000000.0");

    value = value / 10;
    VALUE_CHECK("-900000.0");

    value = value / 10;
    VALUE_CHECK("-90000.0");

    value = value / 10;
    VALUE_CHECK("-9000.0");

    value = value / 10;
    VALUE_CHECK("-900.0");

    value = value / 10;
    VALUE_CHECK("-90.0");

    value = value / 10;
    VALUE_CHECK("-9.0");

    // Cross over
    value = value / 10;
    VALUE_CHECK("-0.9");

    value = value / 10;
    VALUE_CHECK("-0.09");

    value = value / 10;
    VALUE_CHECK("-0.009");

    value = value / 10;
    VALUE_CHECK("-0.0009");

    value = value / 10;
    VALUE_CHECK("-0.00009");

    value = value / 10;
    VALUE_CHECK("-0.000009");

    value = value / 10;
    VALUE_CHECK("-0.0000009");

    value = value / 10;
    VALUE_CHECK("-0.00000009");

    value = value / 10;
    VALUE_CHECK("-0.000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.000000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.0000000000000000000000000000000000009");

    value = value / 10;
    VALUE_CHECK("-0.00000000000000000000000000000000000009");
}

BOOST_AUTO_TEST_CASE(t019)
{
    /* TEST CASE 19: positive divide by negative integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "90000000000000000000000000000000000000.0";
    value.parse(input);
    value = value / -1;
    VALUE_CHECK("-90000000000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9000.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-900.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-90.0");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-9.0");

    // Cross over
    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.9");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.09");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000000000000009");

    value.absval();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000000000000009");
}

BOOST_AUTO_TEST_CASE(t020)
{
    /* TEST CASE 20: negative divide by negative integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    const char* input = "90000000000000000000000000000000000000.0";
    value.parse(input);
    value = value / -1;
    VALUE_CHECK("-90000000000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9000.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-900.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-90.0");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-9.0");

    // Cross over
    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.9");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.09");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.000000000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.0000000000000000000000000000000000009");

    value.negate();
    value = value / -10;
    VALUE_CHECK("-0.00000000000000000000000000000000000009");
}

BOOST_AUTO_TEST_CASE(t021)
{
    /* TEST CASE 21: Dave H's assorted tests
     */

    std::ostringstream output;
    fixed_128_128 value;
    const char* input;
    
    PARSE_VALUE_CHECK_2("99.99", "99.99");
    PARSE_VALUE_CHECK_2("-99.99", "-99.99");
    PARSE_VALUE_CHECK_2("-0.99", "-0.99");
    PARSE_VALUE_CHECK_2("-.99", "-0.99");
    PARSE_VALUE_CHECK_2("-1.99", "-1.99");
    PARSE_VALUE_CHECK_2("+.99", "0.99");
    PARSE_VALUE_CHECK_2("+3.1415", "3.1415");
    PARSE_VALUE_CHECK_2("+3.1415e0", "3.1415");
    PARSE_VALUE_CHECK_2("+3.1415e+0", "3.1415");
    PARSE_VALUE_CHECK_2("3.1415e0", "3.1415");
    PARSE_VALUE_CHECK_2("3.1415e+0", "3.1415");
    PARSE_VALUE_CHECK_2("1000", "1000.0");
    PARSE_VALUE_CHECK_2("1001", "1001.0");
    PARSE_VALUE_CHECK_2("1000e0", "1000.0");
    PARSE_VALUE_CHECK_2("1001e0", "1001.0");
    PARSE_VALUE_CHECK_2("1.00e3", "1000.0");
    PARSE_VALUE_CHECK_2("1.00e+3", "1000.0");
    PARSE_VALUE_CHECK_2("1.00e03", "1000.0");
    PARSE_VALUE_CHECK_2("1.00e+03", "1000.0");
    PARSE_VALUE_CHECK_2("1.0000e3", "1000.0");
    PARSE_VALUE_CHECK_2("1.0001e+03", "1000.1");
    PARSE_VALUE_CHECK_2("1.1415e+03", "1141.5");
    PARSE_VALUE_CHECK_2("59E35", "5900000000000000000000000000000000000.0");
}

BOOST_AUTO_TEST_CASE(t022)
{
    /* TEST CASE 21: more of Dave H's range and accuracy tests
     */

    std::ostringstream output;
    fixed_128_128 value;
    const char* input;

    // large negative values
    PARSE_VALUE_CHECK_2("-1E36", "-1000000000000000000000000000000000000.0");
    PARSE_VALUE_CHECK_2("-1E37", "-10000000000000000000000000000000000000.0");

    // large positive values
    PARSE_VALUE_CHECK_2("1E36", "1000000000000000000000000000000000000.0");
    PARSE_VALUE_CHECK_2("1E37", "10000000000000000000000000000000000000.0");

    // small negative values
    PARSE_VALUE_CHECK_2("-1E-36", "-0.000000000000000000000000000000000001");
    PARSE_VALUE_CHECK_2("-1E-37", "-0.0000000000000000000000000000000000001");
    PARSE_VALUE_CHECK_2("-1E-38", "-0.00000000000000000000000000000000000001");

    // small positive values
    PARSE_VALUE_CHECK_2("1E-36", "0.000000000000000000000000000000000001");
    PARSE_VALUE_CHECK_2("1E-37", "0.0000000000000000000000000000000000001");
    PARSE_VALUE_CHECK_2("1E-38", "0.00000000000000000000000000000000000001");
}

BOOST_AUTO_TEST_CASE(t023)
{
    /* TEST CASE 22: parse negative value with negative exponent (corner case)
     * TODO: this is a stub that needs to be expanded
     */
    std::ostringstream output;
    fixed_128_128 value;
    const char* input;
    
    PARSE_VALUE_CHECK_2("-1E-1", "-0.1"); 
    PARSE_VALUE_CHECK_2("-9.999999999E37", "-99999999990000000000000000000000000000.0");
}

BOOST_AUTO_TEST_CASE(t024)
{
    /* TEST CASE 24: Test basic comparisons between values whose integer 
     * portions are equal and negative.
     */ 
    fixed_128_128 val1, val2;
    val1.parse("-33.0573");
    val2.parse("-33.39685450952594");
    
    BOOST_CHECK(! (val1 == val2));
    BOOST_CHECK(  (val1 != val2));
    BOOST_CHECK(  (val1 > val2));
    BOOST_CHECK(! (val1 < val2));
    BOOST_CHECK(  (val1 >= val2));
    BOOST_CHECK(! (val1 <= val2));
}

BOOST_AUTO_TEST_CASE(t025)
{
    /* TEST CASE 25: random multiply checks
     */ 
    fixed_128_128 value; 
    std::ostringstream output;
    
    const char* input = "0.75";
    value.parse(input);
    value = value * 6;
    VALUE_CHECK("4.5");
    
    input = "123456789.123456789";
    value.parse(input);
    value = value * 123456789;
    VALUE_CHECK("15241578765432099.750190521");
    
    input = "22.7";
    value.parse(input);
    value = value * 99999999;
    VALUE_CHECK("2269999977.3");
}

BOOST_AUTO_TEST_CASE(t026)
{
    /* TEST CASE 26: positive multiply by positive integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    // 0
    const char* input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 0;
    VALUE_CHECK("0.0");
    
    // 1
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1;
    VALUE_CHECK("0.31415926535897932384626433832795028841");
    
    // 10
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10;
    VALUE_CHECK("3.1415926535897932384626433832795028841");
    
    // 100
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100;
    VALUE_CHECK("31.415926535897932384626433832795028841");
    
    // 1000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000;
    VALUE_CHECK("314.15926535897932384626433832795028841");
    
    // 10000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000;
    VALUE_CHECK("3141.5926535897932384626433832795028841");
    
    // 100000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000;
    VALUE_CHECK("31415.926535897932384626433832795028841");
    
    // 1000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000;
    VALUE_CHECK("314159.26535897932384626433832795028841");
    
    // 10000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000;
    VALUE_CHECK("3141592.6535897932384626433832795028841");
    
    // 100000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000;
    VALUE_CHECK("31415926.535897932384626433832795028841");
    
    // 1000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000;
    VALUE_CHECK("314159265.35897932384626433832795028841");
    
    // 10000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000000;
    VALUE_CHECK("3141592653.5897932384626433832795028841");
    
    // 100000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000000;
    VALUE_CHECK("31415926535.897932384626433832795028841");
    
    // 1000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000000;
    VALUE_CHECK("314159265358.97932384626433832795028841");
    
    // 10000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000000000;
    VALUE_CHECK("3141592653589.7932384626433832795028841");
    
    // 100000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000000000;
    VALUE_CHECK("31415926535897.932384626433832795028841");
    
    // 1000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000000000;
    VALUE_CHECK("314159265358979.32384626433832795028841");
    
    // 10000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000000000000;
    VALUE_CHECK("3141592653589793.2384626433832795028841");
    
    // 100000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000000000000;
    VALUE_CHECK("31415926535897932.384626433832795028841");
    
    // 1000000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000000000000;
    VALUE_CHECK("314159265358979323.84626433832795028841");
}

BOOST_AUTO_TEST_CASE(t027)
{
    /* TEST CASE 27: negative multiply by positive integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    // 0
    const char* input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 0;
    VALUE_CHECK("0.0");
    
    // 1
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1;
    VALUE_CHECK("-0.31415926535897932384626433832795028841");
    
    // 10
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10;
    VALUE_CHECK("-3.1415926535897932384626433832795028841");
    
    // 100
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100;
    VALUE_CHECK("-31.415926535897932384626433832795028841");
    
    // 1000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000;
    VALUE_CHECK("-314.15926535897932384626433832795028841");
    
    // 10000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000;
    VALUE_CHECK("-3141.5926535897932384626433832795028841");
    
    // 100000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000;
    VALUE_CHECK("-31415.926535897932384626433832795028841");
    
    // 1000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000;
    VALUE_CHECK("-314159.26535897932384626433832795028841");
    
    // 10000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000;
    VALUE_CHECK("-3141592.6535897932384626433832795028841");
    
    // 100000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000;
    VALUE_CHECK("-31415926.535897932384626433832795028841");
    
    // 1000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000;
    VALUE_CHECK("-314159265.35897932384626433832795028841");
    
    // 10000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000000;
    VALUE_CHECK("-3141592653.5897932384626433832795028841");
    
    // 100000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000000;
    VALUE_CHECK("-31415926535.897932384626433832795028841");
    
    // 1000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000000;
    VALUE_CHECK("-314159265358.97932384626433832795028841");
    
    // 10000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000000000;
    VALUE_CHECK("-3141592653589.7932384626433832795028841");
    
    // 100000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000000000;
    VALUE_CHECK("-31415926535897.932384626433832795028841");
    
    // 1000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000000000;
    VALUE_CHECK("-314159265358979.32384626433832795028841");
    
    // 10000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 10000000000000000;
    VALUE_CHECK("-3141592653589793.2384626433832795028841");
    
    // 100000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 100000000000000000;
    VALUE_CHECK("-31415926535897932.384626433832795028841");
    
    // 1000000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 1000000000000000000;
    VALUE_CHECK("-314159265358979323.84626433832795028841");
}

BOOST_AUTO_TEST_CASE(t028)
{
    /* TEST CASE 28: positive multiply by negative integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    // 0
    const char* input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 0;
    VALUE_CHECK("0.0");
    
    // 1
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1;
    VALUE_CHECK("-0.31415926535897932384626433832795028841");
    
    // 10
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10;
    VALUE_CHECK("-3.1415926535897932384626433832795028841");
    
    // 100
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100;
    VALUE_CHECK("-31.415926535897932384626433832795028841");
    
    // 1000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000;
    VALUE_CHECK("-314.15926535897932384626433832795028841");
    
    // 10000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000;
    VALUE_CHECK("-3141.5926535897932384626433832795028841");
    
    // 100000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000;
    VALUE_CHECK("-31415.926535897932384626433832795028841");
    
    // 1000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000;
    VALUE_CHECK("-314159.26535897932384626433832795028841");
    
    // 10000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000;
    VALUE_CHECK("-3141592.6535897932384626433832795028841");
    
    // 100000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000;
    VALUE_CHECK("-31415926.535897932384626433832795028841");
    
    // 1000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000;
    VALUE_CHECK("-314159265.35897932384626433832795028841");
    
    // 10000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000000;
    VALUE_CHECK("-3141592653.5897932384626433832795028841");
    
    // 100000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000000;
    VALUE_CHECK("-31415926535.897932384626433832795028841");
    
    // 1000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000000;
    VALUE_CHECK("-314159265358.97932384626433832795028841");
    
    // 10000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000000000;
    VALUE_CHECK("-3141592653589.7932384626433832795028841");
    
    // 100000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000000000;
    VALUE_CHECK("-31415926535897.932384626433832795028841");
    
    // 1000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000000000;
    VALUE_CHECK("-314159265358979.32384626433832795028841");
    
    // 10000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000000000000;
    VALUE_CHECK("-3141592653589793.2384626433832795028841");
    
    // 100000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000000000000;
    VALUE_CHECK("-31415926535897932.384626433832795028841");
    
    // 1000000000000000000
    input = "0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000000000000;
    VALUE_CHECK("-314159265358979323.84626433832795028841");
}

BOOST_AUTO_TEST_CASE(t029)
{
    /* TEST CASE 29: negative multiply by negative integer
     */ 
     
    fixed_128_128 value;
    std::ostringstream output;
     
    // 0
    const char* input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * 0;
    VALUE_CHECK("0.0");
    
    // 1
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1;
    VALUE_CHECK("0.31415926535897932384626433832795028841");
    
    // 10
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10;
    VALUE_CHECK("3.1415926535897932384626433832795028841");
    
    // 100
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100;
    VALUE_CHECK("31.415926535897932384626433832795028841");
    
    // 1000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000;
    VALUE_CHECK("314.15926535897932384626433832795028841");
    
    // 10000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000;
    VALUE_CHECK("3141.5926535897932384626433832795028841");
    
    // 100000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000;
    VALUE_CHECK("31415.926535897932384626433832795028841");
    
    // 1000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000;
    VALUE_CHECK("314159.26535897932384626433832795028841");
    
    // 10000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000;
    VALUE_CHECK("3141592.6535897932384626433832795028841");
    
    // 100000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000;
    VALUE_CHECK("31415926.535897932384626433832795028841");
    
    // 1000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000;
    VALUE_CHECK("314159265.35897932384626433832795028841");
    
    // 10000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000000;
    VALUE_CHECK("3141592653.5897932384626433832795028841");
    
    // 100000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000000;
    VALUE_CHECK("31415926535.897932384626433832795028841");
    
    // 1000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000000;
    VALUE_CHECK("314159265358.97932384626433832795028841");
    
    // 10000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000000000;
    VALUE_CHECK("3141592653589.7932384626433832795028841");
    
    // 100000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000000000;
    VALUE_CHECK("31415926535897.932384626433832795028841");
    
    // 1000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000000000;
    VALUE_CHECK("314159265358979.32384626433832795028841");
    
    // 10000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -10000000000000000;
    VALUE_CHECK("3141592653589793.2384626433832795028841");
    
    // 100000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -100000000000000000;
    VALUE_CHECK("31415926535897932.384626433832795028841");
    
    // 1000000000000000000
    input = "-0.31415926535897932384626433832795028841";
    value.parse(input);
    value = value * -1000000000000000000;
    VALUE_CHECK("314159265358979323.84626433832795028841");
}
