Setting persision C++

Discussion in 'Mac Programming' started by swimlikehell, Oct 4, 2006.

  1. swimlikehell macrumors member

    Joined:
    Aug 31, 2006
    #1
    I am trying to round a double number in code to two decimal places using c++, i found the set persision function but i find you can only use that when out putting i need to manipulate a number in memory for testing. if you can please help me, it will be much apreciated. thanks
     
  2. Eraserhead macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #2
    I don't know C++ or if this is the best way, but multiplying the number by 100, add 0.5, convert to an int (assuming C++ rounds a number down when converting to an int), convert back to a double , take off 0.5 and finally divide by 100, should do it.
     
  3. rtharper macrumors regular

    rtharper

    Joined:
    Sep 6, 2006
    Location:
    Oxford, UK
    #3
    May I ask why you need to do this? Because of the way floating point numbers are represented in most programming languages (IEEE-754) makes it less than easy to round out doubles in memory unless you do it as described above.

    There should be no reason that you need to round floating point numbers until you output them. Loss of precision is never a good thing, and you don't want to mess with the internal representation of these numbers too much or your calculations are very likely to become erroneous.

    Technically, when you convert a double to an int it doesn't do any rounding, it truncates the number (i.e. lops off all numbers after the decimal) so that the behavior is analogous to always rounding down. You have to be careful when doing this with floating point numbers, because, for example, when 3 is the result of a floating point calculation it often ends up being 2.999999999... and can get truncated to 2. This is because some numbers are literally unrepresentable in floating point notation. (For example .1 is actually always 0.10000000000000001 because of this limitation, try it in python, which uses IEEE-754 like C++).

    If you really *have* to do this, there are certain arbitrary precision libraries that can let you manipulate numbers this way. Keep in mind though, that they use internal representations that are slow and addition, subtraction, and multiplication become inefficent and are no longer unit cost operations (i.e. the time it takes grows with the length of the number, instead of taking the same time regardless).
     
  4. Krevnik macrumors 68030

    Krevnik

    Joined:
    Sep 8, 2003
    #4
    Another way, if you need to do this is use round(). It is part of BSD, so you have it available on OS X when writing in C++, and it is usually what I use when I positively, absolutely, need to round that troublesome floating point number, or my money back. :p

    So, the routine becomes:

    roundedValue = round(unroundedValue * 10^decimalValuesWanted) / 10^decimalValuesWanted;

    Or, in a simpler form for 2 digits after the decimal:

    y = round(x * 100.0) / 100.0;

    The '.0' for your number literals are important, to ensure that you don't accidentally convert it into an int while rounding it. The good news is that in this form, you don't lose any data out of the mantissa that you weren't expecting to disappear. Of course, this has issues if you are near the upper or lower bounds of the double's exponent, and does nothing if the double has no information about digits that 'small' (such as a number with an arbitrarily large exponent, the mantissa will likely not even reach past the decimal place).

    Although I do wonder why you need to remove precision before you output the number, like the poster above me.
     
  5. swimlikehell thread starter macrumors member

    Joined:
    Aug 31, 2006
    #5
    for some unforeseen reason the program is changing the value of my double and it is failing tests that i have, it is only doing this on ppc not intel so the quick fix was the round so it performs correctly since all i am doing is testing with it.
     
  6. rtharper macrumors regular

    rtharper

    Joined:
    Sep 6, 2006
    Location:
    Oxford, UK
    #6

    Elaborate or post the code, pls =) How is it changing it, at what point, etc.? I for one relish a good debugging challenge.
     
  7. Krevnik macrumors 68030

    Krevnik

    Joined:
    Sep 8, 2003
    #7
    Define 'changing the value' of your double. Floating point is really not as precise as people think, and if you expect full accuracy across the mantissa, odds are that you will likely be disappointed. Usually the platform's ISA documentation will let you know what sort of accuracy to expect from floating point values.

    I had issues where a calculation, while correct, was producing different results than I was expecting (lost accuracy on the last digit of a rather complex mantissa). My unit tests were failing, so I had to come up with a way to validate that the precision of the result was accurate /enough/ for my purposes.
     

Share This Page