views:

191

answers:

4

I am writing an application which does a lot of manipulation with decimal numbers (e.g. 57.65). As multiplications and divisions quickly erode their accuracy, I would like to store the numbers in a class which preserves their accuracy after manipulation, rather than rely on float and double.

I am talking about something like this:

class FloatingPointNumber {
private:
    long m_mantissa;
    int m_dps; // decimal points
    // so for example 57.65 would be represented as m_mantissa=5765, m_dps=2
public:
    // Overloaded function for addition
    FloatingPointNumber operator+(FloatingPointNumber n);
    // Other operator overloads follow
}

While it is possible for me to write such a class, it feels a bit like reinventing the wheel and I am sure that there must be some library class somewhere which does this (although this does not seem to exist in STL).

Does anybody know of such a library? Many thanks.

+3  A: 

There is a list of libraries here.

I have never tried any of them so I can't recommend a single one, however this one is part of the GNU Project so it can't be half bad.

GMan
A: 

If you want to roll your own, Binary Coded Decimal is probably your best bet.

Paul Nathan
A: 
AProgrammer
+4  A: 

Do you mean something like this ?

#include "ttmath/ttmath.h"
#include <iostream>

int main()
{
   // bigdouble consists of 1024*4 bytes for the mantissa
   // and 256*4 bytes for the exponent.
   // This is because my machine is 32-bit!
    typedef ttmath::Big<1024, 256> bigdouble; // <Mantissa, Exponent>

    bigdouble x = 5.05544;
    bigdouble y = "54145454.15484854120248541841854158417";
    bigdouble z = x * y * 0.01;

    std::cout << z;

    return 0;
}

You can specify the number of machine words in the mantissa and the exponent as you like. I have used TTMath to solve Project Euler puzzles, and I am really pleased with it. I think it is relatively stable and the author is very kind if you have questions.


EDIT:: I have also used MAPM in the past. It represents big floats in base 100, so there would be no problem converting decimal numbers to base 100, unlike base 2. TTMAT uses base 2 to represents big floats. It is stable since 2000 as the library page claims. It has been used in many applications as you can see in the library page. It is a C library with a nice C++ wrapper.

MAPM nextPrime(){

    static MAPM prime = 3;
    MAPM retPrime = prime;

    prime += 2;
    while( isPrime( prime ) == false )
     prime += 2;

    return retPrime;
}


BTW, If you are interested in GMP and you are using VS, then you can check the MPIR which is GMP port for Windows ;) for me I find TTMath more than pleasing and easier/faster than all of what I tried because the library does stack allocations without touching the heap in anyway. Basically it is not an arbitrary precision library, you specify the precision at compile-time as shown above.

AraK