commit ef18eb33a9be11434fc5639acf79aa6a16f07b7c
Author: David Sorber <david.sorber@gmail.com>
Date:   Thu Jul 7 10:24:05 2022 -0400

    Correct multiply by integer operator. Also add test cases.

diff --git a/software/fixed/CMakeLists.txt b/software/fixed/CMakeLists.txt
index d1b0c2c..eacc5a0 100644
--- a/software/fixed/CMakeLists.txt
+++ b/software/fixed/CMakeLists.txt
@@ -24,8 +24,11 @@ ADD_EXECUTABLE(fixed_util ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed_util.cc)
 ADD_EXECUTABLE(parse_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/parse_test.cc)
 
 # Test executables
-ADD_EXECUTABLE(fixed_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed_test.cc)
-TARGET_LINK_LIBRARIES(fixed_test ${EXTERNAL_LIBS})
+ADD_EXECUTABLE(fixed64_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed64_test.cc)
+TARGET_LINK_LIBRARIES(fixed64_test ${EXTERNAL_LIBS})
+
+ADD_EXECUTABLE(fixed128_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/fixed128_test.cc)
+TARGET_LINK_LIBRARIES(fixed128_test ${EXTERNAL_LIBS})
 
 ADD_EXECUTABLE(int128_test ${sources} ${CMAKE_CURRENT_SOURCE_DIR}/int128_test.cc)
 TARGET_LINK_LIBRARIES(int128_test ${EXTERNAL_LIBS})
diff --git a/software/fixed/fixed.h b/software/fixed/fixed.h
index 037c9aa..a561a0f 100644
--- a/software/fixed/fixed.h
+++ b/software/fixed/fixed.h
@@ -906,50 +906,78 @@ template<typename I, typename F, typename STI, typename STF>
 constexpr inline fixed<I, F, STI, STF> operator*(
      const fixed<I, F, STI, STF>& x, const int64_t& y)
 {
-    fixed<I, F, STI, STF> newVal;
-    //~ bool negativeDivisorFlag = (y < 0);
-    //~ bool negativeDividendFlag = (x.m_integer < 0) || 
-                                //~ (x.m_integer == fixed<I, F, STI, STF>::NEGATIVE_ZERO);
-    //~ bool negativeZeroFlag = false;
-    //~ I integerX = x.m_integer;
-    //~ if (__unlikely((integerX == fixed<I, F, STI, STF>::NEGATIVE_ZERO)))
-    //~ {
-        //~ integerX = 0;
-        //~ negativeZeroFlag = true;
-    //~ }
-    
-    // Straight multiply for integer portion
-    newVal.m_integer = x.m_integer * y;
+    // Set flag to indicate if result should be negative
+    bool negativeResultFlag = false;
+    I integerX = x.m_integer;
+    if (__unlikely((integerX == fixed<I, F, STI, STF>::NEGATIVE_ZERO)))
+    {
+        integerX = 0;
+        negativeResultFlag = true;
+    }
+    else if (integerX < 0)
+    {
+        integerX *= -1;
+        negativeResultFlag = true;
+    }
     
-    std::cout << "INTEGER: " << newVal.m_integer << std::endl;
+    int64_t multiplier = y;
+    if (multiplier < 0)
+    {
+        // Ensure that multiplier is positive to avoid issues with 
+        // signed/unsigned operations
+        multiplier *= -1;
+        
+        // Toggle negative results flag
+        negativeResultFlag = !negativeResultFlag;
+    }
     
-    std::cout << "Frac digits: " << fixed<I, F, STI, STF>::fractional_decimal_digits << std::endl;
-    std::cout << "Half Frac digits: " << (fixed<I, F, STI, STF>::fractional_decimal_digits / 2) << std::endl;
+    // Multiply integer portion first
+    fixed<I, F, STI, STF> newVal;
+    newVal.m_integer = integerX * multiplier;
     
-    uint32_t index = (fixed<I, F, STI, STF>::fractional_decimal_digits / 2);
+    uint32_t indexUpper = (fixed<I, F, STI, STF>::fractional_decimal_digits / 2);
+    uint32_t indexLower = (fixed<I, F, STI, STF>::fractional_decimal_digits - indexUpper);
     
 #if SUPPORT_128_INTS
-    uint128_t scaler = fixed<I, F, STI, STF>::SCALE_VALUES[index];
+    uint128_t scalerUpper = fixed<I, F, STI, STF>::SCALE_VALUES[indexUpper];
+    uint128_t scalerLower = fixed<I, F, STI, STF>::SCALE_VALUES[indexLower];
 #else
-    uint64_t scaler = fixed<I, F, STI, STF>::SCALE_VALUES[index];
+    uint64_t scalerUpper = fixed<I, F, STI, STF>::SCALE_VALUES[indexUpper];
+    uint64_t scalerLower = fixed<I, F, STI, STF>::SCALE_VALUES[indexLower];
 #endif
+
+    // Compute the lower portion 
+    F fracLower = (x.m_fractional % scalerLower) * multiplier;
     
-    // Handle upper and lower portions of fractional value separarely so that
-    // the integer carry can be handled
-    std::cout << "[1] FRAC upper: " << (x.m_fractional / scaler) << std::endl;
-    F fracUpper = (x.m_fractional / scaler) * y;
-    std::cout << "[2] FRAC upper: " << fracUpper << std::endl;
-    newVal.m_fractional = (fracUpper % (scaler * 10)) * scaler;
-    std::cout << "NEW FRAC upper: " << newVal.m_fractional << std::endl;
+    // Compute lower carry explicitly as it may trigger an additional carry,
+    // then rescale lower portion to remove carry
+    F carryLower = fracLower / scalerLower;
+    fracLower %= scalerLower;
     
-    F carry = (fracUpper / (scaler * 10));
-    std::cout << "Carry: " << carry << std::endl;
-    newVal.m_integer += carry;
+    // Compute upper portion
+    F fracUpper = ((x.m_fractional / scalerLower) * multiplier) + carryLower;
+    newVal.m_fractional = (fracUpper % scalerUpper) * scalerLower;
     
-    F fracLower = (x.m_fractional % scaler) * y;
-    std::cout << "FRAC lower: " << fracLower << std::endl;
+    // Computer integer carry then add it to integer portion
+    newVal.m_integer += (fracUpper / scalerUpper);
+    
+    // Finally add the lower fractional portion, which at this point will not
+    // trigger a carry
     newVal.m_fractional += fracLower;
     
+    // If negative result flag was set ensure that final result is negative
+    if (negativeResultFlag)
+    {
+        if (newVal.m_integer == 0 && newVal.m_fractional > 0)
+        {
+            newVal.m_integer = fixed<I, F, STI, STF>::NEGATIVE_ZERO;
+        }
+        else if (newVal.m_integer > 0)
+        {
+            newVal.m_integer *= -1;
+        }
+    }
+    
     return newVal;
 }
 
diff --git a/software/fixed/fixed128_test.cc b/software/fixed/fixed128_test.cc
new file mode 100644
index 0000000..5fab45a
--- /dev/null
+++ b/software/fixed/fixed128_test.cc
@@ -0,0 +1,3928 @@
+
+#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");
+}
diff --git a/software/fixed/fixed64_test.cc b/software/fixed/fixed64_test.cc
new file mode 100644
index 0000000..82aa77a
--- /dev/null
+++ b/software/fixed/fixed64_test.cc
@@ -0,0 +1,1882 @@
+
+#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;                        \
+    BOOST_CHECK(output.str() == val);
+
+#define PARSE_VALUE_CHECK(val)              \
+    value.parse(input);                     \
+    output.str("");                         \
+    output << value;                        \
+    BOOST_CHECK(output.str() == val);
+
+#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;
+    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);
+    
+    fixed_16_8  f_16_8;
+    fixed_16_16 f_16_16;
+    fixed_16_32 f_16_32;
+    fixed_16_64 f_16_64;
+    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);
+    
+    fixed_32_8  f_32_8;
+    fixed_32_16 f_32_16;
+    fixed_32_32 f_32_32;
+    fixed_32_64 f_32_64;
+    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);
+    
+    fixed_64_8  f_64_8;
+    fixed_64_16 f_64_16;
+    fixed_64_32 f_64_32;
+    fixed_64_64 f_64_64;
+    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_AUTO_TEST_CASE(t001)
+{
+    /* TEST CASE 1: Test basic comparisons
+     */ 
+    fixed_64_64 val1(100, 1, 0);
+    fixed_64_64 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_64_64 val1;
+    fixed_64_64 val2;
+
+    // 1
+    val1.assign(1, 2000000000000000000);
+    val2.parse("1.2");
+    BOOST_CHECK(val1 == val2);
+
+    // 2
+    val1.assign(1, 200000000000000000);
+    val2.parse("1.02");
+    BOOST_CHECK(val1 == val2);
+
+    // 3
+    val1.assign(1, 20000000000000000);
+    val2.parse("1.002");
+    BOOST_CHECK(val1 == val2);
+
+    // 4
+    val1.assign(1, 2000000000000000);
+    val2.parse("1.0002");
+    BOOST_CHECK(val1 == val2);
+
+    // 5
+    val1.assign(1, 200000000000000);
+    val2.parse("1.00002");
+    BOOST_CHECK(val1 == val2);
+
+    // 6
+    val1.assign(1, 20000000000000);
+    val2.parse("1.000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 7
+    val1.assign(1, 2000000000000);
+    val2.parse("1.0000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 8
+    val1.assign(1, 200000000000);
+    val2.parse("1.00000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 9
+    val1.assign(1, 20000000000);
+    val2.parse("1.000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 10
+    val1.assign(1, 2000000000);
+    val2.parse("1.0000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 11
+    val1.assign(1, 200000000);
+    val2.parse("1.00000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 12
+    val1.assign(1, 20000000);
+    val2.parse("1.000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 13
+    val1.assign(1, 2000000);
+    val2.parse("1.0000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 14
+    val1.assign(1, 200000);
+    val2.parse("1.00000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 15
+    val1.assign(1, 20000);
+    val2.parse("1.000000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 16
+    val1.assign(1, 2000);
+    val2.parse("1.0000000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 17
+    val1.assign(1, 200);
+    val2.parse("1.00000000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 18
+    val1.assign(1, 20);
+    val2.parse("1.000000000000000002");
+    BOOST_CHECK(val1 == val2);
+
+    // 19
+    val1.assign(1, 2);
+    val2.parse("1.0000000000000000002");
+    BOOST_CHECK(val1 == val2);
+}
+
+BOOST_AUTO_TEST_CASE(t003)
+{
+    /* TEST CASE 3: Test parsing and printing randomly generated values
+     */ 
+    using theType = fixed_64_64;
+
+    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_64_64 val1(18, 55, 0);
+    fixed_64_64 val2(0, 1855, 0);
+    
+    fixed_64_64 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 = ".00010102030508132134";
+
+    fixed_64_64 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_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "0.0000000000000000001e36";
+    PARSE_VALUE_CHECK("100000000000000000.0");
+    
+    input = "0.0000000000000000001e35";
+    PARSE_VALUE_CHECK("10000000000000000.0");
+    
+    input = "0.0000000000000000001e34";
+    PARSE_VALUE_CHECK("1000000000000000.0");
+    
+    input = "0.0000000000000000001e33";
+    PARSE_VALUE_CHECK("100000000000000.0");
+    
+    input = "0.0000000000000000001e32";
+    PARSE_VALUE_CHECK("10000000000000.0");
+    
+    input = "0.0000000000000000001e31";
+    PARSE_VALUE_CHECK("1000000000000.0");
+    
+    input = "0.0000000000000000001e30";
+    PARSE_VALUE_CHECK("100000000000.0");
+    
+    input = "0.0000000000000000001e29";
+    PARSE_VALUE_CHECK("10000000000.0");
+    
+    input = "0.0000000000000000001e28";
+    PARSE_VALUE_CHECK("1000000000.0");
+    
+    input = "0.0000000000000000001e27";
+    PARSE_VALUE_CHECK("100000000.0");
+    
+    input = "0.0000000000000000001e26";
+    PARSE_VALUE_CHECK("10000000.0");
+    
+    input = "0.0000000000000000001e25";
+    PARSE_VALUE_CHECK("1000000.0");
+    
+    input = "0.0000000000000000001e24";
+    PARSE_VALUE_CHECK("100000.0");
+    
+    input = "0.0000000000000000001e23";
+    PARSE_VALUE_CHECK("10000.0");
+    
+    input = "0.0000000000000000001e22";
+    PARSE_VALUE_CHECK("1000.0");
+    
+    input = "0.0000000000000000001e21";
+    PARSE_VALUE_CHECK("100.0");
+    
+    input = "0.0000000000000000001e20";
+    PARSE_VALUE_CHECK("10.0");
+    
+    input = "0.0000000000000000001e19";
+    PARSE_VALUE_CHECK("1.0");
+    
+    // Cross over
+    input = "0.0000000000000000001e18";
+    PARSE_VALUE_CHECK("0.1");
+    
+    input = "0.0000000000000000001e17";
+    PARSE_VALUE_CHECK("0.01");
+    
+    input = "0.0000000000000000001e16";
+    PARSE_VALUE_CHECK("0.001");
+    
+    input = "0.0000000000000000001e15";
+    PARSE_VALUE_CHECK("0.0001");
+    
+    input = "0.0000000000000000001e14";
+    PARSE_VALUE_CHECK("0.00001");
+    
+    input = "0.0000000000000000001e13";
+    PARSE_VALUE_CHECK("0.000001");
+    
+    input = "0.0000000000000000001e12";
+    PARSE_VALUE_CHECK("0.0000001");
+    
+    input = "0.0000000000000000001e11";
+    PARSE_VALUE_CHECK("0.00000001");
+    
+    input = "0.0000000000000000001e10";
+    PARSE_VALUE_CHECK("0.000000001");
+    
+    input = "0.0000000000000000001e9";
+    PARSE_VALUE_CHECK("0.0000000001");
+    
+    input = "0.0000000000000000001e8";
+    PARSE_VALUE_CHECK("0.00000000001");
+    
+    input = "0.0000000000000000001e7";
+    PARSE_VALUE_CHECK("0.000000000001");
+    
+    input = "0.0000000000000000001e6";
+    PARSE_VALUE_CHECK("0.0000000000001");
+    
+    input = "0.0000000000000000001e5";
+    PARSE_VALUE_CHECK("0.00000000000001");
+    
+    input = "0.0000000000000000001e4";
+    PARSE_VALUE_CHECK("0.000000000000001");
+    
+    input = "0.0000000000000000001e3";
+    PARSE_VALUE_CHECK("0.0000000000000001");
+    
+    input = "0.0000000000000000001e2";
+    PARSE_VALUE_CHECK("0.00000000000000001");
+    
+    input = "0.0000000000000000001e1";
+    PARSE_VALUE_CHECK("0.000000000000000001");
+    
+    input = "0.0000000000000000001e0";
+    PARSE_VALUE_CHECK("0.0000000000000000001");
+}
+
+BOOST_AUTO_TEST_CASE(t007)
+{
+    /* TEST CASE 7: non-zero integer, positive exponent, walking value 
+     * positive+negative test cases
+     */ 
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "1.0000000000000000001e1";
+    PARSE_VALUE_CHECK("10.000000000000000001");
+    
+    input = "1.0000000000000000001e2";
+    PARSE_VALUE_CHECK("100.00000000000000001");
+    
+    input = "1.0000000000000000001e3";
+    PARSE_VALUE_CHECK("1000.0000000000000001");
+    
+    input = "1.0000000000000000001e4";
+    PARSE_VALUE_CHECK("10000.000000000000001");
+    
+    input = "1.0000000000000000001e5";
+    PARSE_VALUE_CHECK("100000.00000000000001");
+    
+    input = "1.0000000000000000001e6";
+    PARSE_VALUE_CHECK("1000000.0000000000001");
+    
+    input = "1.0000000000000000001e7";
+    PARSE_VALUE_CHECK("10000000.000000000001");
+    
+    input = "1.0000000000000000001e8";
+    PARSE_VALUE_CHECK("100000000.00000000001");
+    
+    input = "1.0000000000000000001e9";
+    PARSE_VALUE_CHECK("1000000000.0000000001");
+    
+    input = "1.0000000000000000001e10";
+    PARSE_VALUE_CHECK("10000000000.000000001");
+    
+    input = "1.0000000000000000001e11";
+    PARSE_VALUE_CHECK("100000000000.00000001");
+    
+    input = "1.0000000000000000001e12";
+    PARSE_VALUE_CHECK("1000000000000.0000001");
+    
+    input = "1.0000000000000000001e13";
+    PARSE_VALUE_CHECK("10000000000000.000001");
+    
+    input = "1.0000000000000000001e14";
+    PARSE_VALUE_CHECK("100000000000000.00001");
+    
+    input = "1.0000000000000000001e15";
+    PARSE_VALUE_CHECK("1000000000000000.0001");
+    
+    input = "1.0000000000000000001e16";
+    PARSE_VALUE_CHECK("10000000000000000.001");
+    
+    input = "1.0000000000000000001e17";
+    PARSE_VALUE_CHECK("100000000000000000.01");
+    
+    input = "1.0000000000000000001e18";
+    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.0000000000000000001e37";
+    bool exception = false;
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000000000000001e38";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000000000000001e37";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000000000001e36";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000000000001e35";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000000000001e34";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000000000001e32";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000000001e31";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000000001e30";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000000001e29";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000001e28";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000001e27";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000001e26";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000001e25";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000001e24";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00001e23";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0001e22";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.001e21";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.01e20";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.1e19";
+    PARSE_EXCEPTION_CHECK
+    
+    // Cross over
+    input = "1.0e18";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10.0e17";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100.0e16";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000.0e15";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000.0e14";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000.0e13";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000.0e12";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000.0e11";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000.0e10";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000.0e9";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000000.0e8";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000000.0e7";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000000.0e6";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000000000.0e5";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000000000.0e4";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000000000.0e3";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000000000000.0e2";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000000000000.0e1";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000000000000.0e0";
+    PARSE_EXCEPTION_CHECK
+}
+
+BOOST_AUTO_TEST_CASE(t009)
+{
+    /* TEST CASE 9: zero factional, negative exponent, walking one positive test 
+     * cases
+     */ 
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "100000000000000000.0e-1";
+    PARSE_VALUE_CHECK("10000000000000000.0");
+    
+    input = "100000000000000000.0e-2";
+    PARSE_VALUE_CHECK("1000000000000000.0");
+    
+    input = "100000000000000000.0e-3";
+    PARSE_VALUE_CHECK("100000000000000.0");
+    
+    input = "100000000000000000.0e-4";
+    PARSE_VALUE_CHECK("10000000000000.0");
+    
+    input = "100000000000000000.0e-5";
+    PARSE_VALUE_CHECK("1000000000000.0");
+    
+    input = "100000000000000000.0e-6";
+    PARSE_VALUE_CHECK("100000000000.0");
+    
+    input = "100000000000000000.0e-7";
+    PARSE_VALUE_CHECK("10000000000.0");
+    
+    input = "100000000000000000.0e-8";
+    PARSE_VALUE_CHECK("1000000000.0");
+    
+    input = "100000000000000000.0e-9";
+    PARSE_VALUE_CHECK("100000000.0");
+    
+    input = "100000000000000000.0e-10";
+    PARSE_VALUE_CHECK("10000000.0");
+    
+    input = "100000000000000000.0e-11";
+    PARSE_VALUE_CHECK("1000000.0");
+    
+    input = "100000000000000000.0e-12";
+    PARSE_VALUE_CHECK("100000.0");
+    
+    input = "100000000000000000.0e-13";
+    PARSE_VALUE_CHECK("10000.0");
+    
+    input = "100000000000000000.0e-14";
+    PARSE_VALUE_CHECK("1000.0");
+    
+    input = "100000000000000000.0e-15";
+    PARSE_VALUE_CHECK("100.0");
+    
+    input = "100000000000000000.0e-16";
+    PARSE_VALUE_CHECK("10.0");
+    
+    input = "100000000000000000.0e-17";
+    PARSE_VALUE_CHECK("1.0");
+    
+    // Cross over
+    input = "100000000000000000.0e-18";
+    PARSE_VALUE_CHECK("0.1");
+    
+    input = "100000000000000000.0e-19";
+    PARSE_VALUE_CHECK("0.01");
+    
+    input = "100000000000000000.0e-20";
+    PARSE_VALUE_CHECK("0.001");
+    
+    input = "100000000000000000.0e-21";
+    PARSE_VALUE_CHECK("0.0001");
+    
+    input = "100000000000000000.0e-22";
+    PARSE_VALUE_CHECK("0.00001");
+    
+    input = "100000000000000000.0e-23";
+    PARSE_VALUE_CHECK("0.000001");
+    
+    input = "100000000000000000.0e-24";
+    PARSE_VALUE_CHECK("0.0000001");
+    
+    input = "100000000000000000.0e-25";
+    PARSE_VALUE_CHECK("0.00000001");
+    
+    input = "100000000000000000.0e-26";
+    PARSE_VALUE_CHECK("0.000000001");
+    
+    input = "100000000000000000.0e-27";
+    PARSE_VALUE_CHECK("0.0000000001");
+    
+    input = "100000000000000000.0e-28";
+    PARSE_VALUE_CHECK("0.00000000001");
+    
+    input = "100000000000000000.0e-29";
+    PARSE_VALUE_CHECK("0.000000000001");
+    
+    input = "100000000000000000.0e-30";
+    PARSE_VALUE_CHECK("0.0000000000001");
+    
+    input = "100000000000000000.0e-31";
+    PARSE_VALUE_CHECK("0.00000000000001");
+    
+    input = "100000000000000000.0e-32";
+    PARSE_VALUE_CHECK("0.000000000000001");
+    
+    input = "100000000000000000.0e-33";
+    PARSE_VALUE_CHECK("0.0000000000000001");
+    
+    input = "100000000000000000.0e-34";
+    PARSE_VALUE_CHECK("0.00000000000000001");
+    
+    input = "100000000000000000.0e-35";
+    PARSE_VALUE_CHECK("0.000000000000000001");
+    
+    input = "100000000000000000.0e-36";
+    PARSE_VALUE_CHECK("0.0000000000000000001");
+}
+
+BOOST_AUTO_TEST_CASE(t010)
+{
+    /* TEST CASE 10: non-zero factional, negative exponent, walking value 
+     * positive+negative test cases
+     */ 
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "100000000000000000.1e-1";
+    PARSE_VALUE_CHECK("10000000000000000.01");
+    
+    input = "100000000000000000.1e-2";
+    PARSE_VALUE_CHECK("1000000000000000.001");
+    
+    input = "100000000000000000.1e-3";
+    PARSE_VALUE_CHECK("100000000000000.0001");
+    
+    input = "100000000000000000.1e-4";
+    PARSE_VALUE_CHECK("10000000000000.00001");
+    
+    input = "100000000000000000.1e-5";
+    PARSE_VALUE_CHECK("1000000000000.000001");
+    
+    input = "100000000000000000.1e-6";
+    PARSE_VALUE_CHECK("100000000000.0000001");
+    
+    input = "100000000000000000.1e-7";
+    PARSE_VALUE_CHECK("10000000000.00000001");
+    
+    input = "100000000000000000.1e-8";
+    PARSE_VALUE_CHECK("1000000000.000000001");
+    
+    input = "100000000000000000.1e-9";
+    PARSE_VALUE_CHECK("100000000.0000000001");
+    
+    input = "100000000000000000.1e-10";
+    PARSE_VALUE_CHECK("10000000.00000000001");
+    
+    input = "100000000000000000.1e-11";
+    PARSE_VALUE_CHECK("1000000.000000000001");
+    
+    input = "100000000000000000.1e-12";
+    PARSE_VALUE_CHECK("100000.0000000000001");
+    
+    input = "100000000000000000.1e-13";
+    PARSE_VALUE_CHECK("10000.00000000000001");
+    
+    input = "100000000000000000.1e-14";
+    PARSE_VALUE_CHECK("1000.000000000000001");
+    
+    input = "100000000000000000.1e-15";
+    PARSE_VALUE_CHECK("100.0000000000000001");
+    
+    input = "100000000000000000.1e-16";
+    PARSE_VALUE_CHECK("10.00000000000000001");
+    
+    input = "100000000000000000.1e-17";
+    PARSE_VALUE_CHECK("1.000000000000000001");
+    
+    input = "100000000000000000.1e-18";
+    PARSE_VALUE_CHECK("0.1000000000000000001");
+    
+    input = "100000000000000000.1e-19";
+    bool exception = false;
+    PARSE_EXCEPTION_CHECK
+}
+
+BOOST_AUTO_TEST_CASE(t011)
+{
+    /* TEST CASE 11: zero factional, negative exponent, walking one negative test 
+     * cases
+     */ 
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "100000000000000000.0e-37";
+    bool exception = false;
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000000000000.0e-36";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000000000.0e-35";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000000000.0e-34";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000000000.0e-33";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000000.0e-32";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000000.0e-31";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000000.0e-30";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000000.0e-29";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000000.0e-28";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000000.0e-27";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000000.0e-26";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100000.0e-25";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10000.0e-24";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1000.0e-23";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "100.0e-22";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "10.0e-21";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "1.0e-20";
+    PARSE_EXCEPTION_CHECK
+    
+    // Cross over
+    input = "0.1e-19";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.01e-18";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.001e-17";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0001e-16";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00001e-15";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000001e-14";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000001e-13";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000001e-12";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000001e-11";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000001e-10";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000000001e-9";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000000001e-8";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000000001e-7";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000000000001e-6";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000000000001e-5";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000000000001e-4";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.00000000000000001e-3";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.000000000000000001e-2";
+    PARSE_EXCEPTION_CHECK
+    
+    input = "0.0000000000000000001e-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_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "-1.0000000000000000001e1";
+    PARSE_VALUE_CHECK("-10.000000000000000001");
+    
+    input = "-1.0000000000000000001e2";
+    PARSE_VALUE_CHECK("-100.00000000000000001");
+    
+    input = "-1.0000000000000000001e3";
+    PARSE_VALUE_CHECK("-1000.0000000000000001");
+    
+    input = "-1.0000000000000000001e4";
+    PARSE_VALUE_CHECK("-10000.000000000000001");
+    
+    input = "-1.0000000000000000001e5";
+    PARSE_VALUE_CHECK("-100000.00000000000001");
+    
+    input = "-1.0000000000000000001e6";
+    PARSE_VALUE_CHECK("-1000000.0000000000001");
+    
+    input = "-1.0000000000000000001e7";
+    PARSE_VALUE_CHECK("-10000000.000000000001");
+    
+    input = "-1.0000000000000000001e8";
+    PARSE_VALUE_CHECK("-100000000.00000000001");
+    
+    input = "-1.0000000000000000001e9";
+    PARSE_VALUE_CHECK("-1000000000.0000000001");
+    
+    input = "-1.0000000000000000001e10";
+    PARSE_VALUE_CHECK("-10000000000.000000001");
+    
+    input = "-1.0000000000000000001e11";
+    PARSE_VALUE_CHECK("-100000000000.00000001");
+    
+    input = "-1.0000000000000000001e12";
+    PARSE_VALUE_CHECK("-1000000000000.0000001");
+    
+    input = "-1.0000000000000000001e13";
+    PARSE_VALUE_CHECK("-10000000000000.000001");
+    
+    input = "-1.0000000000000000001e14";
+    PARSE_VALUE_CHECK("-100000000000000.00001");
+    
+    input = "-1.0000000000000000001e15";
+    PARSE_VALUE_CHECK("-1000000000000000.0001");
+    
+    input = "-1.0000000000000000001e16";
+    PARSE_VALUE_CHECK("-10000000000000000.001");
+    
+    input = "-1.0000000000000000001e17";
+    PARSE_VALUE_CHECK("-100000000000000000.01");
+    
+    input = "-1.0000000000000000001e18";
+    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_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "-100000000000000000.1e-1";
+    PARSE_VALUE_CHECK("-10000000000000000.01");
+    
+    input = "-100000000000000000.1e-2";
+    PARSE_VALUE_CHECK("-1000000000000000.001");
+    
+    input = "-100000000000000000.1e-3";
+    PARSE_VALUE_CHECK("-100000000000000.0001");
+    
+    input = "-100000000000000000.1e-4";
+    PARSE_VALUE_CHECK("-10000000000000.00001");
+    
+    input = "-100000000000000000.1e-5";
+    PARSE_VALUE_CHECK("-1000000000000.000001");
+    
+    input = "-100000000000000000.1e-6";
+    PARSE_VALUE_CHECK("-100000000000.0000001");
+    
+    input = "-100000000000000000.1e-7";
+    PARSE_VALUE_CHECK("-10000000000.00000001");
+    
+    input = "-100000000000000000.1e-8";
+    PARSE_VALUE_CHECK("-1000000000.000000001");
+    
+    input = "-100000000000000000.1e-9";
+    PARSE_VALUE_CHECK("-100000000.0000000001");
+    
+    input = "-100000000000000000.1e-10";
+    PARSE_VALUE_CHECK("-10000000.00000000001");
+    
+    input = "-100000000000000000.1e-11";
+    PARSE_VALUE_CHECK("-1000000.000000000001");
+    
+    input = "-100000000000000000.1e-12";
+    PARSE_VALUE_CHECK("-100000.0000000000001");
+    
+    input = "-100000000000000000.1e-13";
+    PARSE_VALUE_CHECK("-10000.00000000000001");
+    
+    input = "-100000000000000000.1e-14";
+    PARSE_VALUE_CHECK("-1000.000000000000001");
+    
+    input = "-100000000000000000.1e-15";
+    PARSE_VALUE_CHECK("-100.0000000000000001");
+    
+    input = "-100000000000000000.1e-16";
+    PARSE_VALUE_CHECK("-10.00000000000000001");
+    
+    input = "-100000000000000000.1e-17";
+    PARSE_VALUE_CHECK("-1.000000000000000001");
+    
+    input = "-100000000000000000.1e-18";
+    PARSE_VALUE_CHECK("-0.1000000000000000001");
+    
+    input = "-100000000000000000.1e-19";
+    bool exception = false;
+    PARSE_EXCEPTION_CHECK
+}
+
+BOOST_AUTO_TEST_CASE(t014)
+{
+    /* TEST CASE 14: LEADING_ZERO=true; negative zero parse
+     */ 
+     
+    fixed_64_64 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");
+}
+
+BOOST_AUTO_TEST_CASE(t015)
+{
+    /* TEST CASE 15: LEADING_ZERO=false; negative zero parse
+     */ 
+     
+    fixed_64_64 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");
+}
+
+BOOST_AUTO_TEST_CASE(t016)
+{
+    /* TEST CASE 16: negative zero comparison
+     */ 
+    fixed_64_64 val1;
+    val1.parse("-0.9");
+    
+    fixed_64_64 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_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "900000000000000000.0";
+    value.parse(input);
+    value = value / 1;
+    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");
+}
+
+BOOST_AUTO_TEST_CASE(t018)
+{
+    /* TEST CASE 18: negative divide by positive integer
+     */ 
+     
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "-900000000000000000.0";
+    value.parse(input);
+    
+    value = value / 1;
+    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");
+}
+
+BOOST_AUTO_TEST_CASE(t019)
+{
+    /* TEST CASE 19: positive divide by negative integer
+     */ 
+     
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "900000000000000000.0";
+    value.parse(input);
+    value = value / -1;
+    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");
+}
+
+BOOST_AUTO_TEST_CASE(t020)
+{
+    /* TEST CASE 20: negative divide by negative integer
+     */ 
+     
+    fixed_64_64 value;
+    std::ostringstream output;
+     
+    const char* input = "-900000000000000000.0";
+    value.parse(input);
+    value = value / -1;
+    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");
+}
+
+BOOST_AUTO_TEST_CASE(t021)
+{
+    /* TEST CASE 21: Dave H's 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 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_64_64 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));
+}
diff --git a/software/fixed/fixed_util.cc b/software/fixed/fixed_util.cc
index 9a84910..8dc7308 100644
--- a/software/fixed/fixed_util.cc
+++ b/software/fixed/fixed_util.cc
@@ -8,11 +8,22 @@
 #include "fixed.h"
 #include "int128.h"
 
+#define USE_INT128 1
+
 // g++ fixed_test.cc -o fixed_test
 int main(int argc, char** argv)
 {
     std::cout << "Fixed Type Test Util\n" << std::endl;
     
+    fixed_128_128 value;
+    const char* input = "-0.31415926535897932384626433832795028841";
+    value.parse(input);
+    std::cout << "[0] Value: " << value << std::endl;
+    value = value * 0;
+    std::cout << "[1] Value: " << value << std::endl;
+    
+    
+#if 0
     fixed_64_64 val;
     fixed_64_64 val2;
     val.parse("0.314159263538979");
@@ -22,6 +33,19 @@ int main(int argc, char** argv)
     
     val2 = val * 86;
     std::cout << "[3] Val: " << val2 << std::endl;
+    
+    std::cout << "\n--------------------------------------------------------------------\n" << std::endl;
+    
+    fixed_128_128 val3;
+    fixed_128_128 val4;
+    val3.parse("0.314159263538979");
+    std::cout << "[1] Val: " << val3 << std::endl;
+    val4 = val3 * 10;
+    std::cout << "[2] Val: " << val4 << std::endl;
+    
+    val4 = val3 * 86;
+    std::cout << "[3] Val: " << val4 << std::endl;
+#endif
 
 #if 0
     //-------------------------------------------------------------------------
diff --git a/software/read_test/src/URingExecDriver.cc b/software/read_test/src/URingExecDriver.cc
new file mode 100644
index 0000000..604ac75
--- /dev/null
+++ b/software/read_test/src/URingExecDriver.cc
@@ -0,0 +1,130 @@
+/********************************************************************
+* This software is "commercial computer software" as defined in the *
+* Federal Acquisition Regulations and is subject to BlackLynx       *
+* Inc's standard End User License Agreement.                        *
+*                                                                   *
+* CONFIDENTIAL - All source code is the propriety and confidential  *
+* information of BlackLynx Inc.                                     *
+*                                                                   *
+* Copyright 2022 BlackLynx Inc.                                     *
+* Unpublished -- all rights reserved under the copyright laws       *
+* of the United States.                                             *
+********************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+#include "URingExecDriver.h"
+#include "Utilities/ChunkConstants.h"
+#include "Utilities/FileUtils.h"
+#include "Utilities/SearchLynxConfiguration.h"
+#include "Utilities/BufferAllocator.h"
+
+    
+BlackLynx::SearchLynx::URingExecDriver::URingExecDriver(
+    const std::string& inputFile,
+    uint32_t numReaderThreads)
+    : ExecDriver(inputFile, numReaderThreads)
+{
+}
+    
+BlackLynx::SearchLynx::URingExecDriver::~URingExecDriver()
+{
+}
+
+void BlackLynx::SearchLynx::URingExecDriver::start()
+{
+    // Start threads in reverse order staring with cleanup thread    
+    p_cleanupThread = new std::thread(&BlackLynx::SearchLynx::ExecDriver::cleanupThreadBody, 
+                                      this,
+                                      &m_cleanupQueue);
+    
+    // Start specified number of reader threads
+    for (uint32_t idx = 0; idx < m_numReaderThreads; ++idx)
+    {
+        std::thread* thisThread = 
+                new std::thread(&BlackLynx::SearchLynx::URingExecDriver::readerThreadBody, 
+                                this,
+                                &m_readerQueue,
+                                &m_cleanupQueue);
+        m_readerThreads.push_back(thisThread);
+    }
+    
+    // Start setup thread body
+    p_setupThread = new std::thread(&BlackLynx::SearchLynx::ExecDriver::setupThreadBody, 
+                                    this,
+                                    &m_readerQueue,
+                                    m_numReaderThreads);
+}
+
+void BlackLynx::SearchLynx::URingExecDriver::readerThreadBody(
+    chunk_queue_t* inQueue,
+    chunk_queue_t* outQueue)
+{
+    BlnxLog(error) << "URING READER";
+    
+    const uint32_t QUEUE_DEPTH = 32;
+    const uint32_t IO_SIZE = 4194304;
+    const uint32_t MIN_SIZE_ALIGN = 512;
+    // Setup IO context
+    
+    // Open the file
+    int fd = -1;
+//    int fd = ::open(r_inputFile.c_str(), O_RDONLY | O_DIRECT);
+//    if (fd < 0)
+//    {
+//        BlnxLog(error) << "Unable to open file: "  << r_inputFile;
+//        return;
+//    }
+    
+    Chunk* chunk = nullptr;
+    std::string prevFilename("");
+    
+//    std::ofstream output("chunk.bin");
+    
+    while (true)
+    {
+        chunk = inQueue->pop_front();
+        
+        // Check for terminator
+        if (chunk == nullptr)
+        {
+            break;
+        }
+        
+        if (prevFilename != chunk->m_filename)
+        {
+            // Open the file
+            fd = ::open(r_inputFile.c_str(), O_RDONLY | O_DIRECT);
+            if (fd < 0)
+            {
+                BlnxLog(error) << "Unable to open file: "  << r_inputFile;
+                return;
+            }
+        }
+        
+        // Grab a buffer to hold the chunk data
+        chunk->allocateBuffer();
+        
+        // Determine how many IOs we need
+//        std::string test(chunk->p_chunkData, 30);
+//        BlnxLog(debug) << "CHUNK " << chunk->m_chunkId << " DATA: " << test;
+        
+//        output.write(chunk->p_chunkData, chunk->m_chunkSize);
+
+        outQueue->push_back(chunk);
+    }
+    
+//    output.close();
+    
+    // Release file descriptor
+    ::close(fd);
+    
+    // Destroy the IO context
+    io_destroy(context);
+    
+    // Send terminator to clean up thread
+    m_cleanupQueue.push_back(nullptr);
+}
\ No newline at end of file
diff --git a/software/read_test/src/URingExecDriver.h b/software/read_test/src/URingExecDriver.h
new file mode 100644
index 0000000..e4eea10
--- /dev/null
+++ b/software/read_test/src/URingExecDriver.h
@@ -0,0 +1,56 @@
+/********************************************************************
+* This software is "commercial computer software" as defined in the *
+* Federal Acquisition Regulations and is subject to BlackLynx       *
+* Inc's standard End User License Agreement.                        *
+*                                                                   *
+* CONFIDENTIAL - All source code is the propriety and confidential  *
+* information of BlackLynx Inc.                                     *
+*                                                                   *
+* Copyright 2022 BlackLynx Inc.                                     *
+* Unpublished -- all rights reserved under the copyright laws       *
+* of the United States.                                             *
+********************************************************************/
+
+#ifndef __BLACKLYNX_URING_EXECDRIVER_H__
+#define __BLACKLYNX_URING_EXECDRIVER_H__
+
+#include <cstdint>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <vector>
+
+#include "Chunk.h"
+#include "ExecDriver.h"
+#include "Utilities/ProtectedAndSynchronizedQueue.h"
+
+
+namespace BlackLynx
+{
+namespace SearchLynx
+{
+
+class URingExecDriver : public ExecDriver
+{
+public:
+    
+    URingExecDriver(
+        const std::string& inputFile,
+        uint32_t numReaderThreads);
+    
+    ~URingExecDriver() override;
+    
+    void start() override;
+    
+private:
+    
+    void readerThreadBody(
+        chunk_queue_t* inQueue,
+        chunk_queue_t* outQueue) override;
+    
+};
+
+}
+}
+
+#endif // __BLACKLYNX_URING_EXECDRIVER_H__
\ No newline at end of file
