I have the following code:
#include<stdio.h>
void main(){
int x;
x=1%9*4/5+8*3/9%2-9;
printf("%d \n", x);
}
The output of the program is -9. When I tried to breakdown the code according to operator precedence(* / %,Multiplication/division/modulus,left-to-right) answer turns out to be -8.
Below is the breakdown of the code:
x=1%9*4/5+8*3/9%2-9;
x=1%36/5+24/9%2-9;
x=1%7+2%2-9;
x=1+0-9;
x=-8;
Can someone explain how the output is -9.
It appears that you consider modulo to have lower precedence than multiplication and division, when in fact it does not. Instead of
x = (1 % ((9 * 4) / 5)) + (((8 * 3) / 9) % 2) - 9;
the expression you have really represents
x = (((1 % 9) * 4) / 5) + (((8 * 3) / 9) % 2) - 9;
The modulo in the first summand is applied before the multiplication and division.
x = 1%9*4/5+8*3/9%2-9
== 1*4/5+24/9%2-9
== 4/5+2%2-9
== 0+0-9
== -9
All these operators *, /, % belong to the category of multiplicative operators. Their grouping is more clearly described in the C++ Standard (the same is valid for the C Standard) 5.6 Multiplicative operators:
1 The multiplicative operators *, /, and % group left-to-right.
Thus this expression statement
x=1%9*4/5+8*3/9%2-9;
is equivalent to the following statement
x = (( ( 1 % 9 ) * 4 ) / 5 ) + ( ( ( 8 * 3 ) / 9 ) % 2 ) - 9;
Related
This question already has answers here:
Modulo operation with negative numbers
(12 answers)
Closed 1 year ago.
I would be grateful if somebody could help me with this question.
A C program contains the following declarations and initial assignments.
int i = 8, j = 5;
float x = 0.005, y = - 0.01;
char c = 'c', d = 'd';
Determine the value of the following expression using values assigned to the variables for the expression:
(i - 3 * j) % ( c + 2 *d)/ (x - y )
I tried this manually first:
( i- 3 * j) % ( c + 2 *d ) / ( x - y)
( 8 - 3*5) % ( 99 + 2 * 100 ) / ( 0.005 - (-0.01) )
( -7 ) % ( 299 ) / ( 0.015 )
Keeping precedence and associativity in mind, I used the mod operator first:
( 292 ) / ( 0.015 )
Which gave the answer 19466.66.
This does not match with the answer given in the book or when I used this in codeblocks, both of which gave the answer as - 466.6667
The codeblocks program is as below
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 8,j = 5, c = 'c',d = 'd';
float x = 0.005, y = -0.01, a = 0.0; // a is the float variable to which the value is assigned
a = (i-3*j)%(c+2*d)/(x-y);
printf("%f\n",a);
return 0;
}
The crux of this is the integer part before division:
(i-3*j)%(c+2*d)
Where that evaluates to:
(8-3*5) % (99 + 2 * 100)
(8-15) % (99 + 200)
-7 % 299
So now it depends on what definition of modulo is being used by C, as there are several it could be. C interprets this as -7 while other languages always map to the 0 to 298 range.
The rest is just simple division.
You have to use division at the end (and once) of your calculation to keep the precision.
With division, you can lose precision. See the butterfly effect Wikipedia page why it can make huge differences.
You can work with fractions and only divide when you print them.
In a C program I was trying the below operations (Just to check the behavior)
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
It gave me output as (2, -2 , -2) in gcc. I was expecting a positive result every time. Can a modulus be negative? Can anybody explain this behavior?
C99 requires that when a/b is representable:
(a/b) * b + a%b shall equal a
This makes sense, logically. Right?
Let's see what this leads to:
Example A. 5/(-3) is -1
=> (-1) * (-3) + 5%(-3) = 5
This can only happen if 5%(-3) is 2.
Example B. (-5)/3 is -1
=> (-1) * 3 + (-5)%3 = -5
This can only happen if (-5)%3 is -2
The % operator in C is not the modulo operator but the remainder operator.
Modulo and remainder operators differ with respect to negative values.
With a remainder operator, the sign of the result is the same as the sign of the dividend (numerator) while with a modulo operator the sign of the result is the same as the divisor (denominator).
C defines the % operation for a % b as:
a == (a / b * b) + a % b
with / the integer division with truncation towards 0. That's the truncation that is done towards 0 (and not towards negative inifinity) that defines the % as a remainder operator rather than a modulo operator.
Based on the C99 Specification: a == (a / b) * b + a % b
We can write a function to calculate (a % b) == a - (a / b) * b!
int remainder(int a, int b)
{
return a - (a / b) * b;
}
For modulo operation, we can have the following function (assuming b > 0)
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}
My conclusion is that a % b in C is a remainder operation and NOT a modulo operation.
I don't think there isn't any need to check if the number is negative.
A simple function to find the positive modulo would be this -
Edit: Assuming N > 0 and N + N - 1 <= INT_MAX
int modulo(int x,int N){
return (x % N + N) %N;
}
This will work for both positive and negative values of x.
Original P.S: also as pointed out by #chux, If your x and N may reach something like INT_MAX-1 and INT_MAX respectively, just replace int with long long int.
And If they are crossing limits of long long as well (i.e. near LLONG_MAX), then you shall handle positive and negative cases separately as described in other answers here.
Can a modulus be negative?
% can be negative as it is the remainder operator, the remainder after division, not after Euclidean_division. Since C99 the result may be 0, negative or positive.
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
The modulo OP wanted is a classic Euclidean modulo, not %.
I was expecting a positive result every time.
To perform a Euclidean modulo that is well defined whenever a/b is defined, a,b are of any sign and the result is never negative:
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
modulo_Euclidean( 7, 3) --> 1
modulo_Euclidean( 7, -3) --> 1
modulo_Euclidean(-7, 3) --> 2
modulo_Euclidean(-7, -3) --> 2
The other answers have explained in C99 or later, division of integers involving negative operands always truncate towards zero.
Note that, in C89, whether the result round upward or downward is implementation-defined. Because (a/b) * b + a%b equals a in all standards, the result of % involving negative operands is also implementation-defined in C89.
According to C99 standard, section 6.5.5
Multiplicative operators, the following is required:
(a / b) * b + a % b = a
Conclusion
The sign of the result of a remainder operation, according
to C99, is the same as the dividend's one.
Let's see some examples (dividend / divisor):
When only dividend is negative
(-3 / 2) * 2 + -3 % 2 = -3
(-3 / 2) * 2 = -2
(-3 % 2) must be -1
When only divisor is negative
(3 / -2) * -2 + 3 % -2 = 3
(3 / -2) * -2 = 2
(3 % -2) must be 1
When both divisor and dividend are negative
(-3 / -2) * -2 + -3 % -2 = -3
(-3 / -2) * -2 = -2
(-3 % -2) must be -1
6.5.5 Multiplicative operators
Syntax
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
Constraints
Each of the operands shall have arithmetic type. The
operands of the % operator shall have integer type.
Semantics
The usual arithmetic conversions are performed on the
operands.
The result of the binary * operator is the product of
the operands.
The result of the / operator is the quotient from
the division of the first operand by the second; the
result of the % operator is the remainder. In both
operations, if the value of the second operand is zero,
the behavior is undefined.
When integers are divided, the result of the / operator
is the algebraic quotient with any fractional part
discarded [1]. If the quotient a/b is representable,
the expression (a/b)*b + a%b shall equal a.
[1]: This is often called "truncation toward zero".
The result of Modulo operation depends on the sign of numerator, and thus you're getting -2 for y and z
Here's the reference
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
Integer Division
This section describes functions for performing integer division.
These functions are redundant in the GNU C library, since in GNU C the
'/' operator always rounds towards zero. But in other C
implementations, '/' may round differently with negative arguments.
div and ldiv are useful because they specify how to round the
quotient: towards zero. The remainder has the same sign as the
numerator.
In Mathematics, where these conventions stem from, there is no assertion that modulo arithmetic should yield a positive result.
Eg.
1 mod 5 = 1, but it can also equal -4. That is, 1/5 yields a remainder 1 from 0 or -4 from 5. (Both factors of 5)
Similarly,
-1 mod 5 = -1, but it can also equal 4. That is, -1/5 yields a remainder -1 from 0 or 4 from -5. (Both factors of 5)
For further reading look into equivalence classes in Mathematics.
Modulus operator gives the remainder.
Modulus operator in c usually takes the sign of the numerator
x = 5 % (-3) - here numerator is positive hence it results in 2
y = (-5) % (3) - here numerator is negative hence it results -2
z = (-5) % (-3) - here numerator is negative hence it results -2
Also modulus(remainder) operator can only be used with integer type and cannot be used with floating point.
I believe it's more useful to think of mod as it's defined in abstract arithmetic; not as an operation, but as a whole different class of arithmetic, with different elements, and different operators. That means addition in mod 3 is not the same as the "normal" addition; that is; integer addition.
So when you do:
5 % -3
You are trying to map the integer 5 to an element in the set of mod -3. These are the elements of mod -3:
{ 0, -2, -1 }
So:
0 => 0, 1 => -2, 2 => -1, 3 => 0, 4 => -2, 5 => -1
Say you have to stay up for some reason 30 hours, how many hours will you have left of that day? 30 mod -24.
But what C implements is not mod, it's a remainder. Anyway, the point is that it does make sense to return negatives.
It seems the problem is that / is not floor operation.
int mod(int m, float n)
{
return m - floor(m/n)*n;
}
In a C program I was trying the below operations (Just to check the behavior)
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
It gave me output as (2, -2 , -2) in gcc. I was expecting a positive result every time. Can a modulus be negative? Can anybody explain this behavior?
C99 requires that when a/b is representable:
(a/b) * b + a%b shall equal a
This makes sense, logically. Right?
Let's see what this leads to:
Example A. 5/(-3) is -1
=> (-1) * (-3) + 5%(-3) = 5
This can only happen if 5%(-3) is 2.
Example B. (-5)/3 is -1
=> (-1) * 3 + (-5)%3 = -5
This can only happen if (-5)%3 is -2
The % operator in C is not the modulo operator but the remainder operator.
Modulo and remainder operators differ with respect to negative values.
With a remainder operator, the sign of the result is the same as the sign of the dividend (numerator) while with a modulo operator the sign of the result is the same as the divisor (denominator).
C defines the % operation for a % b as:
a == (a / b * b) + a % b
with / the integer division with truncation towards 0. That's the truncation that is done towards 0 (and not towards negative inifinity) that defines the % as a remainder operator rather than a modulo operator.
Based on the C99 Specification: a == (a / b) * b + a % b
We can write a function to calculate (a % b) == a - (a / b) * b!
int remainder(int a, int b)
{
return a - (a / b) * b;
}
For modulo operation, we can have the following function (assuming b > 0)
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}
My conclusion is that a % b in C is a remainder operation and NOT a modulo operation.
I don't think there isn't any need to check if the number is negative.
A simple function to find the positive modulo would be this -
Edit: Assuming N > 0 and N + N - 1 <= INT_MAX
int modulo(int x,int N){
return (x % N + N) %N;
}
This will work for both positive and negative values of x.
Original P.S: also as pointed out by #chux, If your x and N may reach something like INT_MAX-1 and INT_MAX respectively, just replace int with long long int.
And If they are crossing limits of long long as well (i.e. near LLONG_MAX), then you shall handle positive and negative cases separately as described in other answers here.
Can a modulus be negative?
% can be negative as it is the remainder operator, the remainder after division, not after Euclidean_division. Since C99 the result may be 0, negative or positive.
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
The modulo OP wanted is a classic Euclidean modulo, not %.
I was expecting a positive result every time.
To perform a Euclidean modulo that is well defined whenever a/b is defined, a,b are of any sign and the result is never negative:
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
modulo_Euclidean( 7, 3) --> 1
modulo_Euclidean( 7, -3) --> 1
modulo_Euclidean(-7, 3) --> 2
modulo_Euclidean(-7, -3) --> 2
The other answers have explained in C99 or later, division of integers involving negative operands always truncate towards zero.
Note that, in C89, whether the result round upward or downward is implementation-defined. Because (a/b) * b + a%b equals a in all standards, the result of % involving negative operands is also implementation-defined in C89.
According to C99 standard, section 6.5.5
Multiplicative operators, the following is required:
(a / b) * b + a % b = a
Conclusion
The sign of the result of a remainder operation, according
to C99, is the same as the dividend's one.
Let's see some examples (dividend / divisor):
When only dividend is negative
(-3 / 2) * 2 + -3 % 2 = -3
(-3 / 2) * 2 = -2
(-3 % 2) must be -1
When only divisor is negative
(3 / -2) * -2 + 3 % -2 = 3
(3 / -2) * -2 = 2
(3 % -2) must be 1
When both divisor and dividend are negative
(-3 / -2) * -2 + -3 % -2 = -3
(-3 / -2) * -2 = -2
(-3 % -2) must be -1
6.5.5 Multiplicative operators
Syntax
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
Constraints
Each of the operands shall have arithmetic type. The
operands of the % operator shall have integer type.
Semantics
The usual arithmetic conversions are performed on the
operands.
The result of the binary * operator is the product of
the operands.
The result of the / operator is the quotient from
the division of the first operand by the second; the
result of the % operator is the remainder. In both
operations, if the value of the second operand is zero,
the behavior is undefined.
When integers are divided, the result of the / operator
is the algebraic quotient with any fractional part
discarded [1]. If the quotient a/b is representable,
the expression (a/b)*b + a%b shall equal a.
[1]: This is often called "truncation toward zero".
The result of Modulo operation depends on the sign of numerator, and thus you're getting -2 for y and z
Here's the reference
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
Integer Division
This section describes functions for performing integer division.
These functions are redundant in the GNU C library, since in GNU C the
'/' operator always rounds towards zero. But in other C
implementations, '/' may round differently with negative arguments.
div and ldiv are useful because they specify how to round the
quotient: towards zero. The remainder has the same sign as the
numerator.
In Mathematics, where these conventions stem from, there is no assertion that modulo arithmetic should yield a positive result.
Eg.
1 mod 5 = 1, but it can also equal -4. That is, 1/5 yields a remainder 1 from 0 or -4 from 5. (Both factors of 5)
Similarly,
-1 mod 5 = -1, but it can also equal 4. That is, -1/5 yields a remainder -1 from 0 or 4 from -5. (Both factors of 5)
For further reading look into equivalence classes in Mathematics.
Modulus operator gives the remainder.
Modulus operator in c usually takes the sign of the numerator
x = 5 % (-3) - here numerator is positive hence it results in 2
y = (-5) % (3) - here numerator is negative hence it results -2
z = (-5) % (-3) - here numerator is negative hence it results -2
Also modulus(remainder) operator can only be used with integer type and cannot be used with floating point.
I believe it's more useful to think of mod as it's defined in abstract arithmetic; not as an operation, but as a whole different class of arithmetic, with different elements, and different operators. That means addition in mod 3 is not the same as the "normal" addition; that is; integer addition.
So when you do:
5 % -3
You are trying to map the integer 5 to an element in the set of mod -3. These are the elements of mod -3:
{ 0, -2, -1 }
So:
0 => 0, 1 => -2, 2 => -1, 3 => 0, 4 => -2, 5 => -1
Say you have to stay up for some reason 30 hours, how many hours will you have left of that day? 30 mod -24.
But what C implements is not mod, it's a remainder. Anyway, the point is that it does make sense to return negatives.
It seems the problem is that / is not floor operation.
int mod(int m, float n)
{
return m - floor(m/n)*n;
}
I have a problem understanding the output of the code. Any explanation please...
#include<stdio.h>
void main()
{
int x=2,y=5;
x*=y+1;
printf("%d",x);
}
The output is as 12. But as per my understanding x*=y+1;is x=x*y+1; but as per operator precedence x*y should be evaluated followed by adding 1 so it should be 10+1=11. But it is 12 — can anyone explain please?
It will be evaluated as
x = x * (y + 1);
so
x = 2 * ( 5 + 1 )
x = 12
What's going on here is how the order of operations happens in programming.
Yes, if you were to have this equation x*y+1 it would be (x * y ) + 1 and result in eleven.
But in programming, the equation to the right of the = sign is solved for prior to being modified by the symbol proceeding the = sign. In this equation it is multiplied.
So x *= y + 1 is actually x = x * ( y + 1 ) which would be 12.
^ In this case, the asterisk(*) is multiplying the entire equation on the right hand side by x and then assigning that outcome to x.
It is translated into : x = x*(y+1);
So very obviously it prints out 12.
Your understanding is correct but it's somthing like this:
x*=y+1; => x = x * (y + 1);
Now apply BODMAS
x *= y + 1 is x = x * (y + 1)
Operator + has higher precedence than operator *=.
x*=y; works like x=x*y;
and here x*=(y+1) is getting expanded like x = x * (y + 1);
*= and similar ones are a type of C assignment operators, i.e. these operators are different from * and alike.
Now from C operator precedence, these operators have lowest precedence (higher than ,) hence y + 1 will be evaluated first, then *= will be evaluated and result will be assigned to x.
It evaluates as
x = x * (y + 1);
so
x = 2 * (5 + 1) = 12
Take a look at Operators order, you will see why in this case it is evaluated like that.
Here from operator procedure in c you can see
Addition/subtraction assignment has lower procedure than simply add operation.
so here
x*=y+1;
+ get executed first.
so
x = x * (6)
so x = 2 * 6
x = 12;
I have done a ton of research as to how the order of evaluation goes - but cannot figure out how it would go for this equation:
z = !x + y * z / 4 % 2 - 1
My best guess is (from left to right):
z = !x + {[([y * z] / 4) % 2] - 1}
Order of evaluation and operator precedence are two different things.
Your best guess is correct. All the multiplicative operators * / % have the same precedence, and bind left-to-right. The additive operator - has lower precedence. The unary ! operator binds more tightly than the multiplicative or additive operators. And the assignment operator = has very low precedence (but still higher than the comma operator).
So this:
z = !x + y * z / 4 % 2 - 1
is equivalent to this:
z = (!x) + (((y * z) / 4) % 2) - 1
But the operands may legally be evaluated in any order (except for certain operators like &&, ||, ,, which impose left-to-right evaluation). If the operands are simple variables, this probably doesn't matter, but in something like:
z = func(x) * func(y);
the two function calls may occur in either order.
If you can't understand it, rewrite your expression
z = !x + y * z / 4 % 2 - 1
notx = !x; /* you can move this line 1, 2, or 3 lines down */
tmp1 = y * z;
tmp2 = tmp1 / 4;
tmp3 = tmp2 % 2;
tmp4 = notx + tmp3;
tmp5 = tmp4 - 1;