What to use for monetary precision.



  • here is my question I make an application which reads sales files which are written in binary strcutures though let's say.

    QString test = "1.16";
    double dblvalueoftest = test.ToDouble();

    will show 1.1599999999999999999 in the debuger windows is that the real value of my double or is it just an issue with the debugger
    not being able to understand the precision? or is it just that a double of value 1.16 is never perfect?

    what is a solution for alot of rounding, that is not using two integers in C++.

    thanks in advance.



  • [quote author="dsylebee" date="1306472363"]or is it just that a double of value 1.16 is never perfect?[/quote]this



  • You will never have "perfect" precision with float point. It can be achieved only with fixed point real numbers.



  • This comes due to the binary representation of a number. a floating point value in C (and also C++) is represented by a so called fraction and exponent (see "wikipedia":http://en.wikipedia.org/wiki/Double_precision ).





  • It is not a bug. Use fixed precision math. There are specialist libraries for that available, for depending on what you are trying to do, you may be able to get away with a poor mans solution and use a integer type (qint64 comes to mind) where that represents the number of, say, 1/10000th units of your currency. That is: $1 would be represented by 10000, in that case. Only in your code, you would "fix" the decimal point between the fourth and fifth (decimal) digit.

    Note that if you need to start doing multiplications or devisions (or other operations like that) on fixed point numbers, you need to be very careful. Try what happens if you don't compensate for the fixed point in a multiplication...

    If you choose to use a normal integer type, I would recommend you make a special typedef for it. That way, at least it is clear in your code what the type represents, and how it should be handled. That makes it more maintainable.



  • [quote author="Andre" date="1306482061"]Note that if you need to start doing multiplications or devisions (or other operations like that) on fixed point numbers, you need to be very careful. Try what happens if you don't compensate for the fixed point in a multiplication...

    If you choose to use a normal integer type, I would recommend you make a special typedef for it. That way, at least it is clear in your code what the type represents, and how it should be handled. That makes it more maintainable. [/quote]You should rather make it a class than a typedef, since you need to store the knowledge of how to work with the data somewhere.



  • Making it a class is certainly possible and perhaps desireable, but - entirely depending on what you want to achieve - might be complete overkill. It would make you implement all kinds of operations on it yourself, that you otherwise get for free. Including the ones that are perfectly save to do (addition, substraction, multiplication with normal (non-fixed point scalars), etc.). If you are that seriously using fixed point math, I think you're better off using an existing library providing all that for you. The suggestion of using a typedef was only for the case where you use the poor-mans fixed-point math solution of using a normal integer and multiply all the values you store in it by 10,000 or so.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.