2

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.

mskfisher
  • 3,291
  • 4
  • 35
  • 48
  • Yes the datatype you're looking for is called decimal. It's not a floating point type however. It's the datatype to use when representing money for example. – Skurmedel Aug 12 '09 at 19:05
  • 3
    ...? He asked if such a library exists. You said, 'Yes, ...' – GManNickG Aug 12 '09 at 19:09
  • Well then I expressed myself in a fuzzy manner. What I was trying to say was that this type is commonly called "decimal", which would give him pointers what to look for. – Skurmedel Aug 12 '09 at 19:11
  • If you want to represent money, just store it in terms of the small units of money, and then convert it later if for example you want to represent it to a human. – KTC Aug 12 '09 at 19:13
  • I know that the data type decimal exists in C#, but not in C++ hence the original question. –  Aug 12 '09 at 19:30
  • Forgive me for trying to help. – Skurmedel Aug 12 '09 at 19:33

5 Answers5

5

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.

Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
3

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.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
0

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

Paul Nathan
  • 39,638
  • 28
  • 112
  • 212
0
AProgrammer
  • 51,233
  • 8
  • 91
  • 143
0

I have no experience with these libraries, but just as a matter of awareness, there have been 2 major developments that I think are relevant to this question in the last few years...

  1. "posits" - a new floating-point format that is more efficient and less "messy" than IEEE754.
  2. C# 11 has introduced "static abstract interface members" which enables (for our purposes) implementing new numeric types while getting all the same benefits of the built-in numeric types in terms of operator overloading, etc... i.e. truly generic numeric types in C#.

I know of no implementations of "posits" in C#, nor is C# 11 released yet. But again -- these are salient developments related to the question.

burton
  • 421
  • 4
  • 13