-1

While working on a project, I stumbled upon an issue. Some arithmetic using Preprocessor defined values resulted in 0.00.

#include <stdio.h>

#define PINGCOUNT 10

int main()
{
    int successful = 5;
    int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;
    printf("%.2lf\n", lossPercentage);

    return 0;
}

I re-ran this code in an online compiler and got the same result. I'm not sure if I am wording this poorly, but I'm having trouble finding information about this topic online.

The above code would work if I first declared int count = PINGCOUNT, then replaced the PINGCOUNT instances with count. Additionally, I tried using PINGCOUNT in some simple subtraction/addition and it worked properly. Is there something obvious that I'm missing?

chrk
  • 4,037
  • 2
  • 39
  • 47
  • 1
    `#define PINGCOUNT ((int)10)` or `#define PINGCOUNT ((double)10)` – AK_ Nov 21 '15 at 12:01
  • also integers are **whole** values. only float or double can be fractions. – AK_ Nov 21 '15 at 12:04
  • @user42187 : I wonder how the above code would work if you first declared int count = PINGCOUNT, then replaced the PINGCOUNT instances with count. It works but still gives you 0.00. doesn't it? – sjsam Nov 21 '15 at 12:55

3 Answers3

3

Since everything is an int in your program, you're doing integer division, so (PINGCOUNT - successful) / PINGCOUNT equals to 0, which multiplied by 100 is still 0.

Then, you're trying to print the result as a double, which invokes undefined behaviour.

Changing this line

int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;

to:

double lossPercentage = (PINGCOUNT - successful) * 100.0 / PINGCOUNT;

makes sure the result is of type double, performing the operations as you intended.

chrk
  • 4,037
  • 2
  • 39
  • 47
0

try : int lossPercentage = (PINGCOUNT - successful) * 100 / PINGCOUNT;

it's simply a problem with integers , (PINGCOUNT - successful) / PINGCOUNT) is equal 0 and * 100 is still 0

atrebbi
  • 553
  • 3
  • 20
0

Can Preprocessor values be used for arithmetic in C?

Yes.

But why you shouldn't use macros?

Because they rearrange the program text before the compiler proper sees it, macros are also a major problem for many programming support tools. (Courtesy : Bjane Stroustrup)

Though he said that in a C++ perspective, it is equally applicable to C programs as well.

Now what happened in your program

You are getting unexpected results not because you have used a preprocessor value in your calculation. It is because you have used a type that cannot store floating point values, ie int.

You could in fact change

int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;

to

double lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;

An alternative would be to use C-Style cast in your preprocessor definition.

Change

#define PINGCOUNT 10

to

#define PINGCOUNT ((float)10)

and retain

int lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100;

But you lose precision here and there is a cost associated with C-Style Cast - Problems can only be found at run-time. See this SO question.

Community
  • 1
  • 1
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • Sorry, the original code was : double lossPercentage = ((PINGCOUNT - successful) / PINGCOUNT) * 100; but this still produces 0 as a result. – user42187 Nov 21 '15 at 13:11
  • Did the use of c-style cast in the preprocessor directive work for you? – sjsam Nov 21 '15 at 13:23
  • Stroustrup's comments about macros are nice and all.... C++ has a (horrifying) templates system that can do most of the things that can be done with macros. C doesn't. In C sometimes macros is the best way to do something. That or perl... – AK_ Nov 21 '15 at 13:36