Math operation doesn't return expected result - c

I'm using a function, but the code will not work. I broke the function down into its parts and tried to understand what's going on myself. I got this:
int res;
res = (1 / 2) * 2 + 2;
printf("%d", res);
Calculating myself:
(1 /2) = 0.5
0.5 * 2 = 1
1 + 2 = 3
(1 / 2) * 2 + 2 = 3, right?
However, when I run the code it gives me an output of '2', instead of '3'.
When I try this: (making '(1 / 2)' to '0.5')
int res;
res = 0.5 * 2 + 2;
printf("%d", res);
I get an expected output of '3', which is weird because the example above is theoretically the same as the lower one. Does it have to do with my compiler not knowing simple math prioritising rules?

1/2 actually tries to return an integer result (0), which multiplied by 2 is also 0.
You can try typecasting it
float res;
res = (float)1/(float)2 * 2 + 2;
printf("%f", res);
It will force the result to be a float result (0.5), which will lead to the correct answer

Related

Understanding double and integers

Absolute beginner programmer and wondered if you could help me understand some results and terms. I'm trying to follow the programs logic and how it works out certain values. The following case is an example to try and understand these concepts.
#include <stdio.h>
void main ()
{
int inum = 11;
double dnum = 2.56;
double dec_result;
int int_result;
dec_result = inum / 4 + (3.0 * inum) / 5;
printf("value in dec_result is %.2f\n", dec_result);
dec_result = (double) inum / 4 + (3 * inum) / 5;
printf("value in dec_result is %.2f\n", dec_result);
int_result = (int) dnum * 10 + 1;
printf("value in int_result is %d\n", int_result);
int_result = (int) (dnum * 10 + 1);
printf("value in int_result is %d\n", int_result);
}
I know the results as I've run it through Visual Basic. What I'm struggling to follow is how it works it out.
My workings:
inum and dnum I presume are 'names for values' and could be used interchangeably with say x or y. Same with int_result and dec_result.
First dec_result is 8.60
dec_result = inum / 4 + (3.0 * inum) / 5;
11 (an integer) / 4 + (3.0 * 11) / 5
11 (an integer) / 4 + (33.0) / 5
Then I'm a bit lost... 2.75 + 6.6?
Somehow, due to inum being an integer, value is truncated if written as fraction. But as remaining inum in the brackets is multiplied first then it becomes a decimal place number?
It's displayed as decimal places as specified by the placeholder and specified by data type double.
Second dec_result is 8.75
dec_result = (double) inum / 4 + ( 3 * inum) / 5;
= as double is a cast operator you change inum from int to double, so therefore:
= (double) inum / 4 + (33) / 5;
Then = inum/4 becomes 2.75 + 33/5
Why does the 33/5 bit become 6?
It's displayed as decimal places as specified by the placeholder and specified by data type double.
int_result = (int) dnum * 10 + 1;
= cast operator alters dnum a double to integer so 2.56 becomes 2
= 2 * 10 + 1
= 20 + 1
= 21
should be an integer as specified before the bracket and also %d placeholder means to provide the value as number with no decimal point.
int_result = (int) (dnum * 10 + 1);
I got:
= (int) (2.56 * 10 + 1)
= (int) (25.6 + 1)
= (int) (26.6)
= 26
because the value should be an integer as specified before the bracket and also %d placeholder means to provide the value as number with no decimal point.
Is my logic correct?
The C compiler will do integer arithmetic only if both operands are integers (integer / integer, integer + integer, etc.), otherwise it will do floating point arithmetic (double / integer, double + integer, etc.)
First result:
11 (an integer) / 4 + (33.0) / 5
The first part (11/4) is computed with integer arithmetic, so the answer is 2
The second part (33.0 / 5) is computed with floating point arithmetic, so the answer is 6.6 and the sum is 8.6
Second result:
(double) inum / 4 + (33) / 5;
"(double) inum / 4" is computed using floating point arithmetic, so the answer is 2.75.
"33 / 5" is computed using integer arithmetic, so the answer is 6, and the sum is 8.75
In the following:
int_result = (int) dnum * 10 + 1;
The variable dnum is first cast to an integer, so integer arithmetic is used: 2 * 10 + 1 == 21
And finally:
int_result = (int) (dnum * 10 + 1);
In this case, "dnum * 10 + 1" is computed first, which is done using floating point arithmetic: 2.56 * 10 + 1 == 26.6. Then the cast - (int) - truncates to give 26.
When an arithmetic operator is given two integer arguments, the result is an integers, so any fraction is discarded. So11 / 4is2, not2.75`. But when you combine an integer with a floating point, the integer is first converted to floating point, and a floating point result is returned.
As a result:
dec_result = inum / 4 + (3.0 * inum) / 5;
= 11 / 4 + (3.0 * 11) / 5
= 11 / 4 + (3.0 * 11.0) / 5
= 2 + 33.0 / 5
= 2 + 6.6
= 8.6

Multiplication and division: weird output in c

I read that * (multiplication) has has higher presedence than / (division). Thus if there is an equation with both * and /, then * must take place first.
But I've seen a program that output something strange
#include<stdio.h>
#define SQUARE(x) x*x
int main()
{
float s=10, u=30, t=2, a;
a = 2*(s-u*t)/SQUARE(t);
printf("Result = %f", a);
return 0;
}
When running this, I thought that the output would be -25, but in fact it was -100.
When I looked for the explanation it was
Step 2: a = 2*(s-u*t)/SQUARE(t); becomes,
// Here SQUARE(t) is replaced by macro to t*t
=> a = 2 * (10 - 30 * 2) / t * t;
=> a = 2 * (10 - 30 * 2) / 2 * 2;
=> a = 2 * (10 - 60) / 2 * 2;
=> a = 2 * (-50) / 2 * 2 ;
/*till here it's OK*/
/*why it divided -50 by 2 before multiplying 2*2 and -50*2 */
=> a = 2 * (-25) * 2 ;
=> a = (-50) * 2 ;
=> a = -100;
Can any one explain please?
Parenthesis paranoia! Your macro should be:
#define SQUARE(X) ((x)*(x))
Or else precedence rules and macro expansion will do weird things. Your macro:
100 / SQUARE(2)
will expand to:
100 / 2*2
and that is read as:
(100/2) * 2
which is 100, not 25.
Other anomaly, not in your code is if you try to square an expression:
SQUARE(2+2)
will expand to
2+2*2+2
which is 8, not the expected 16.
Conclusion: in macros write a lot of parentheses. Everywhere.
Division and muliplication have the same precedence, and are thus evaluated from left to right. http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
It does not do what you think it does: after the step marked /*till here it's OK*/, the operations proceed in their regular order for multiplicative operators, i.e. left to right:
=> a = 2 * (-50) / 2 * 2 ;
/*till here it's OK*/
=> a = -100 / 2 * 2 ; // Division
=> a = -50 * 2 ; // Multiplication
=> a = -100 ; // Done
Your code is a perfect example of why one needs to be very careful with macros: parenthesizing macro's parameters would fix this particular problem, but some problems are simply non-fixable. For example, your macro would remain unsuitable for expressions with side effects:
#define SQUARE(X) ((x)*(x))
// Still not good:
int a = 2;
// Undefined behavior, because ((a++)*(a++)) uses expressions with side effects without a sequence point
int b = SQUARE(a++);
For this reason, you would be better off making SQUARE a function.

How to get the correct value of / and % operators?

I want to do the following things:
I use a variable int a to keep the input from the console, and then I do the following:
int b = a / 16;
When a is 64 or 32, I get 4 or 2. But if a is 63, I expect to get 4, but I get 3. Are there any ways in C to get a rounded value?
Edit. More details:
rang 1 to 16 should get 1,
rang 17 to 32 should get 2,
rang 33 to 48 should get 3,
rang 49 to 64 should get 4
When you use the division operator / with two int arguments, it will returns an int representing the truncated result.
You can get a rounded-up division without using floating point numbers, like this :
int a;
int den = 16;
int b = (a + den - 1) / den;
Which will give you what you expect :
a ∈ [0], b = 0 / 16 = 0,
a ∈ [1, 16], b = [16, 31] / 16 = 1,
a ∈ [17, 32], b = [32, 47] / 16 = 2,
a ∈ [33, 48], b = [48, 63] / 16 = 3,
a ∈ [49, 64], b = [64, 79] / 16 = 4,
...
Note that this only work if a and b are positives, and beware of the possible overflow of a + den.
If a + den is suspected to possibly overflow, then you could use another version of this expression :
int b = (a - 1) / den + 1;
The only downside is that it will return 1 when a = 0. If that's an issue, you can add something like :
int b = (a - 1) / den + 1 - !a;
Note that you can also handle negative values of a the same way (round away from zero) :
int b = (a > 0) ? (a - 1) / den + 1 : (a - den + 1) / den;
Integer division / in C does not do rouding, instead, it does truncation.
Solution
int ans, newNo;
int no = 63; // Given number
int dNo = 16; // Divider
newNo = (no % dNo) ? (dNo - (no % dNo) + no) : no; // Round off number
ans = newNo / dNo;
Edit
Optimize solution
ans = (no / dNo) + !!(no % dNo);
whatever you are trying is conceptualy not correct but still if you want the same result as you said in your question , you can try for standard function double ceil(double x) defined in math.h
Rounds x upward, returning the smallest integral value that is not less than x.
The simplest way to get what you want is to use float numbers.
#include <math.h>
#include <stdio.h>
int main(void)
{
double a = 63.0;
double b = 16.0;
printf("%d", (int) round(a / b));
return 0;
}
Carefully pay attention when casting from float numbers to int, and vise versa. For example, round(63/16) is incorrect. It returns a double, but achieves nothing, since the literals 63 and 16 are integers. The division is done before the value is passed to the function. The correct way is to make sure that one or both operands are of type double: round(63.0 / 16.0)
You can try using following
int b = (int)ceil((double)a/16);
Since C int division always rounds towards zero, a simple trick you can use to make it round evenly is to add "0.5" to the number before the rounding occurs. For example, if you want to divide by 32, use
x = (a+16)/32;
or more generally, for a/b, where a and b are both positive:
x = (a+b/2)/b;
Unfortunately negative numbers complicate it a bit, because if the result is negative, then you need to subtract 0.5 rather than add it. That's no problem if you already know it will be positive or negative when you're writing the code, but if you to deal with both positive and negative answers it becomes messy. You could do it like this...
x = (a+((a/b>0)?1:-1)*(b/2)) / b;
but by that stage it's starting to get pretty complex - it's probably better to just cast to float and use the round function.
--
[Edit] as zakinster pointed out, although the question asked for 'round' values, the examples given actually require ceil. The way to do that with ints would be:
x = (a+b-1)/b;
again, if the answer can be negative this gets complicated:
x = (a+((a/b>0)?1:-1)*(b-1)) / b;
I'll leave my original response for even rounding just in case someone is interested.

Can someone check my arithmetic for this beginner C program?

I am writing a program in C that calculates this formula:
(source: crewtonramoneshouseofmath.com)
here is the line of code (I am just using + instead of the +-):
x = ((-1 * b) + (sqrt(pow(b, 2) - 4 * a * c)))/(4 * a);
I am not getting the correct root. For example if a = 1, b=-2, and c=-2 it SHOULD be 2.73. Instead I am getting 1.37.
Been staring at the code and I don't see the mistake. Can someone point it out for me?
x = (...) / (4 * a)
Shouldn't this be 2 * a?
It's interesting that 1.37 (what you're getting) is about half of 2.73 (what you want) and, lo and behold, there it is in your denominator, dividing by 4a instead of 2a.
Personally, I would write that expression as:
x = (-b + sqrt (b * b - 4 * a * c)) / (2 * a);
since it more closely matches the equation you're trying to duplicate (the -1 * b is better expressed as -b) and I find calling pow to get a simple square to be unnecessary where b * b does the same job without a function call.
x1 = ((-1 * bcoeff) + (sqrt(pow(bcoeff, 2) - 4 * acoeff * ccoeff)))/(2 * acoeff);
Check yourself here: .../(4 * acoeff)
While this question has already been answered and your error pointed out. I would just like to mention that breaking the problem down into more lines would increase its readability and potentially reduce mistakes made.
float den = 2 * a;
float num1 = (-1 * b);
float num2 = pow(b ,2) - (4 * a * c);
float x = (num1 + sqrt(num2))/ den;

C math calculation not working as expected

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. :)
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.
You're using integer math.
9/100 = 0.
100 + (100 * (0) = 100.
Your calculators use floating point math, and can handle decimals appropriately.
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)));
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.
int test = 100 + (100 * (9 / 100));
9/100 = 0
0 * 100 = 0
100 + 0 = 100
you are using integer division so 9 / 100 is zero so test = 100 + 0 = 100
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));
The answer of 9/10 gets truncated to 0, and then you multiply that by 100, and then add 100 to it.
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.
You should be using floating point arithmetic so 9/100 becomes 0.09.
int test = 100.0 + (100.0 * 9.0 / 100.0);
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);

Resources