1

I am writing a program in C.

Is there any way of determining the number of decimal places in a float number (i.e. 0.123 = 3, 0.123456 = 6 etc.)?

Other than converting the number to a string and using string functions to pull the characters after the decimal place?

I have a function named computeFare()

float computeFare()
{
  totalFare =  (3.40 + basicFare) * (1 + surchargePercent);
  return totalFare; // **in this case totalFare = 34.567**
}

printf("Total fare is $%.2f\n", 
            computeFare());

Result : Total fare is $34.56

I did this and it returned 34.56... I want it to be $34.57

Thanks, Lawrence.

Lawrence Wong
  • 1,129
  • 4
  • 24
  • 40
  • 1
    What problem are you trying to solve? – Kerrek SB Sep 04 '12 at 12:41
  • 1
    Check out this link http://stackoverflow.com/questions/1083304/c-c-counting-the-number-of-decimals –  Sep 04 '12 at 12:41
  • float computeFare() { totalFare = (3.40 + basicFare) * (1 + surchargePercent); return totalFare; // in this case totalFare = 34.567 } printf("Total fare is $%.2f\n", computeFare()); I did this and it returned 34.56... I want it to be $34.57 – Lawrence Wong Sep 04 '12 at 12:48
  • You need to round computeFare to the nearest 2 decimal places *before* you print, because %.2f always truncates without rounding. That should solve your problem. – Ian Goldby Sep 04 '12 at 13:00
  • I see. How would I be able to do that? Is there any library available in C that is able to round my answer to the nearest 2 decimal places? I google but I can't seems to find such library. – Lawrence Wong Sep 04 '12 at 13:02
  • There's no standard library function to round to a certain number of decimal places. But one way is to multiply by 100.0, add 0.5, round down ([floor()](http://msdn.microsoft.com/en-us/library/x39715t6%28v=vs.71%29.aspx)), and then divide by 100.0. – Ian Goldby Sep 04 '12 at 13:05

5 Answers5

5

Not really, the number of decimal places is a function of the internal representation of the number. What you see when you display the number is, is the number as a string for printing.

So if you are interested in the displayed value, you can control the number of decimal places with formatting directives in the first place e.g., %5.2f, or use the string function approach as you mention in your post after the fact once you have the number as a string.

Also, as an aside, would you count trailing zeros?

Perhaps it would be helpful to state your goal for wanting to do this? There might be other ways to accomplish what you are looking to do.

Update:

Based on your update, the problem is really not counting decimal places, rather you are running into represenation issue/rounding errors (not that uncommon). The problem is that some fractional values can't be exactly represented in base 2. Here's an exhaustive explanation: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Take a look at this SO question: Understanding floating point representation errors; what's wrong with my thinking?

You can try this approach to round the value:

float rounded_val = floorf(value * 100.0 + 0.5) / 100.0; 

Wikipeadia has a whole article on rounding.

Community
  • 1
  • 1
Levon
  • 138,105
  • 33
  • 200
  • 191
  • float computeFare() { totalFare = (3.40 + basicFare) * (1 + surchargePercent); return totalFare; // in this case totalFare = 34.567 } printf("Total fare is $%.2f\n", computeFare()); I did this and it returned 34.56... I want it to be $34.57 – Lawrence Wong Sep 04 '12 at 12:44
  • I can't really tell from the comment (the formatting is hard here, better to update your post), but it seems to me you are running into the fact that the binary representation of floating values given base 2 representation will potentially give you some small errors. Some fractional values can't be exactly represented in base 2. – Levon Sep 04 '12 at 12:50
  • @LawrenceWong See my update .. it relates to my previous comment – Levon Sep 04 '12 at 12:56
  • I saw your updated comment. So how do I resolve my issue? Any suggestion? Based on the link you provided, someone actually mentioned using decimal instead of float and double. But I don't think decimal is available in C. – Lawrence Wong Sep 04 '12 at 13:00
  • @LawrenceWong I updated my answer once more, but essentially you can try this: `float rounded_val = floorf(value * 100.0 + 0.5) / 100.0;` – Levon Sep 04 '12 at 15:47
4

The numbers will (in general) be stored in base 2, so fractional numbers are unlikely to correspond precisely to concise decimal strings. In order to get neat decimals, you're probably going to have to round first.

Thom Smith
  • 13,916
  • 6
  • 45
  • 91
  • 2
    Just to clarify, a number like 0.1 (decimal) cannot be represented exactly as a floating point number. So if you convert this to a string (e.g. sprintf()) you might get "0.1" exactly or you might get "0.10000000149011612". So a simple-minded 'count the digits right of the decimal point' algorithm could give a wildly different answer that depends purely on how sprintf() rounds non-exact numbers. – Ian Goldby Sep 04 '12 at 12:47
2

With printf you can specify the amount of decimal places.

  • %.0f equals no decimal places
  • %.4f equals float showing four decimal places
Toribio
  • 3,963
  • 3
  • 34
  • 48
Kay Warner
  • 191
  • 1
  • 2
  • 11
  • float computeFare() { totalFare = (3.40 + basicFare) * (1 + surchargePercent); return totalFare; // in this case totalFare = 34.567 } printf("Total fare is $%.2f\n", computeFare()); I did this and it returned 34.56... I want it to be $34.57 – Lawrence Wong Sep 04 '12 at 12:47
1

A. I wouldn't think so. even if you could get the mantisa (the exponent value) it would be in base 2.
B. Moreover, floating numbers are not accurate so most likely that if you don't have a perfect round number that you have infinite number of decimal places. you wouldn't see them when you print the number cause there are getting cut.

Roee Gavirel
  • 18,955
  • 12
  • 67
  • 94
0

After your latest edit, it sounds like you just want to round, not that you really care about the number of decimal places in a number.

If this is the case you can use code like this:

#include <math.h>

float computeFare() 
{   
    float totalFare;
    totalFare =  (3.40 + basicFare) * (1 + surchargePercent);
    totalFare = floorf(totalFare * 100 + 0.5) / 100; //round the answer
    return totalFare; // **in this case totalFare = 34.567** 
}  
printf("Total fare is $%.2f\n",              computeFare()); 
Mike
  • 47,263
  • 29
  • 113
  • 177