-3

I have a double value and I want to shorten it to 6 digits after the integer part. For example:

double aDouble = 418.73684210526318;
double convertedDouble = conversion (aDouble); 

convertedDouble must be 418.736842

I implemented this solution:

convertedDouble = floor(aDouble * 1000000) / 1000000;

However, convertedDouble is 418.73684200000002, not 418.73684200000000

What can I do?

Anamort
  • 321
  • 4
  • 14
  • Just set precision when printing the value? – Some programmer dude May 08 '15 at 08:23
  • 1
    possible duplicate of [Rounding Number to 2 Decimal Places in C](http://stackoverflow.com/questions/1343890/rounding-number-to-2-decimal-places-in-c) – Levi May 08 '15 at 08:25
  • 1
    Also, you do know that not all values can be represented precisely? – Some programmer dude May 08 '15 at 08:27
  • I don't want to print the value. I use it in a decision tree which is builded as if-then format. – Anamort May 08 '15 at 08:48
  • 1
    What you are asking is not possible, because floating point values don't use decimal format internally. Maybe you should create new question where you describe the high level problem you are trying to solve? – user694733 May 08 '15 at 08:55
  • Please note: no matter how you manipulate your double value, it is **not safe** to compare two double variables with `==`, so probably you need a different approach in your decision tree. – DrKoch May 08 '15 at 09:12
  • Convert the double to an integer by multiplying with 1000000. This will leave only 3 significant decimals for the whole part, which is not a problem with the example `418` but may be for others. If so, convert to *two* integers: the whole part and the fraction. – Jongware May 08 '15 at 09:18
  • @DrKoch I would not say it is unsafe, it just doesn't behave like most people expect it to behave. – user694733 May 08 '15 at 11:52
  • @user694733 True, "usafe" is the wrong term. Probably better: "It does not work" (in most cases) – DrKoch May 08 '15 at 11:55
  • Can you make each node in your decision tree represent a range, rather than a single value? – Patricia Shanahan May 08 '15 at 13:37

2 Answers2

1

You should distinguish between internal representation of a double (64 Bits, about 17 decimal places) and the string representation of such a double which is used to show the value in a printout, the GUI etc.

Usually it makes no sense to change the internal representation i.e. the actual value of a double but use a "print format" to create a string representation with the required number of decimal places (and rounding)

DrKoch
  • 8,904
  • 2
  • 30
  • 43
1

The simplest solution to the decision tree problem you mention in comments would be to think in terms of the range of doubles that should go to a particular branch of the tree, rather than a single double.

However, here is an attempt at the conversion function you asked for:

double conversion(double in){
    char wkStr[1000];
    snprintf(wkStr, sizeof(wkStr), "%.6f", in);
    double result;
    sscanf(wkStr, "%lf", &result);
    return result;
}

As you have discovered, finding the double closest to the result of rounding a given double to a limited number of decimal places is not a trivial problem. It can be treated as the combination of two non-trivial but already solved problems:

  1. Format the input double as a decimal string rounded to the required number of decimal places.
  2. Parse that string to get the closest double to the rounded decimal value.
Patricia Shanahan
  • 24,883
  • 2
  • 34
  • 68