tags:

views:

306

answers:

11

I have the following in a program (part of a much larger function, but this is the relevant testing bit):

int test = 100 + (100 * (9 / 100));
sprintf (buf, "Test: %d\n\r", test);
display_to_pc (buf, player);

Basically it amounts to:

x = a + (a * (b / 100))

Where a is a given figure, b is a percentage modifier, and x is the result (the original plus a percentage of the original)... I hope that makes sense.

It gives me:

Test: 100

I thought the math in my head might be wrong, but I've checked several calculators and even the expression evaluator in my IDE, and they all give me the expected result of 109 for the first expression.

Can anyone enlighten me as to what I'm missing here?

Thanks much. :)

+3  A: 

int test = 100 + (100 * (9 / 100));

9/100 = 0

0 * 100 = 0

100 + 0 = 100

Kevin
+1  A: 

The answer of 9/10 gets truncated to 0, and then you multiply that by 100, and then add 100 to it.

Kyle Walsh
+8  A: 

You're using integer math.

9/100 = 0.

100 + (100 * (0) = 100.

Your calculators use floating point math, and can handle decimals appropriately.

Michael
+2  A: 

you are using integer division so 9 / 100 is zero so test = 100 + 0 = 100

SDX2000
+14  A: 

Replace

int test = 100 + (100 * (9 / 100));

with

int test = 100 + (100 * 9 / 100);
// x = a + (a * b / 100)

and it will work as expected. 9 / 100 is performed using integer division; the nearest integer to .09 is 0 (and 0 * 100 is still 0).

Doing the multiplication first results in 900 / 100, which gives you the 9 that you were expecting.

If you need more than integer precision, you may need to go the floating point route.

Daniel LeCheminant
I think you'd be better off doing an explicit cast or using a floating point constant as depending on the order of evaluation is subject to breaking if you ever refactor the code. Putting in an explicit cast at least warns the next programmer (who could be you) that this needs to be floating point.
tvanfosson
I don't know; I've been doing "multiply before divide" scaling (obviously for numbers that won't overflow) for so long that it seems pretty natural to me; I try not to get into FP if I can avoid it. I'll agree that caution in this case is wise.
Daniel LeCheminant
@tvanfosson: if someone changes the order of operations, they're changing the behavior of the code. No one is going to do that and expect it to work the same way. And it doesn't need to be floating point... sometimes you want integer math, and this looks like one of those times.
rmeador
+3  A: 

Your mistake is that 9 / 100 is interpreted as integer division, and evaluates to 0 and not 0.09.

You can write 9 / 100.0 instead, or rearrange the expression.

Thomas Padron-McCarthy
+4  A: 

As others have pointed out, the problem is that you are doing integer arithmethic. You need to do the calculation as floating point by casting the variable to double or using a double constant, then allow truncation to give you just the integer portion.

x = a + (a * (b / 100.0));

or

x = a + (a * ((double)b / 100)));
tvanfosson
+1  A: 

Change:

int test = 100 + (100 * (9 / 100));

to

int test = (int)(100 + (100 * (9 / 100.0)));

and see if it works as expected.

EDIT: wow. Lots of answers while I was typing. Most of them will work, too.

BoltBait
+1  A: 

You should be using floating point arithmetic so 9/100 becomes 0.09.

int test = 100.0 + (100.0 * 9.0 / 100.0);

Scottie T
+2  A: 

Use Daniel L's answer if you will only be working with expressions that will result in whole integer values. If the values you'll be working with are less clean, use double literals instead of integer literals:

int test = 100.0 + (100.0 * (9.0 / 100.0));
Welbog
A: 

You are using integers for your variable types, so the inner most expression (9 / 100) will result in a 0. Then the next expression would be 100 * 0, which is 0, and finally 100 + 0...

To get your desired result try using float instead:

float test = 100.0 + (100.0 * (9.0 / 100.0));

printf("result: %0.2f\n", test);

Evan