Im having trubles to understand what it means when there is define and then two xor expressions. what this define does?
i try to send x=8, y=7 and the result was that x=15 and y=8
why its happand?
this is the program:
#define FUNC(a,b) a^=b; b ^=a;
int main(){
int x=8,y= 7;
FUNC(x,y);
printf("%d %d\n",x, y);
}
It is just the same as
int main(){
int x=8,y= 7;
x^=y; y ^=x;;
printf("%d %d\n",x, y);
}
because the define will just be a simple text substitution, i.e. all places with awill be replaced by x and all places with b will be replaced with y.
The ^ is a bit wise XOR operator.
So first x = 8 ^ 7 = 15 then y = 7 ^ 15 = 8
This is because XOR produce 1 when one of the bits but not both are 1
x = 8 = 0b00000000000000000000000000001000 // Assuming 32 bit int
y = 7 = 0b00000000000000000000000000000111 // Assuming 32 bit int
x=x^y = 0b00000000000000000000000000001111 = 15
x = 15 = 0b00000000000000000000000000001111 // Assuming 32 bit int
y = 7 = 0b00000000000000000000000000000111 // Assuming 32 bit int
y=y^x = 0b00000000000000000000000000001000 = 8
^^^
Zero because both bits are 1
More to the original question:
This macro has the first two steps of the bit-wise method to exchange two values:
(1) a ^= b
(2) b ^= a
(3) a ^= b
Let's expand this a little: let x = a; y = b, and we'll trace the algebra through terms of x and y. First, replace each "update" with its full expression:
(1) a = a ^ b
(2) b = b ^ a
(3) a = a ^ b
Now, substitute x and y, trickling down from top to bottom:
(1) a = x ^ y
(2) b = y ^ (x ^ y)
(3) a = (x ^ y) ^ (y ^ (x ^ y))
Drop the parentheses and rearrange terms:
(1) a = x ^ y
(2) b = x ^ y ^ y
(3) a = x ^ x ^ y ^ y ^ y
... leaving us with b = x; a = y
Now, since you have only the first two steps, your final result is
b = x (original value of a)
a = x ^ y (a.k.a. a ^ b)
Does that explain the immediate problem for you?
The canonical way to #define multi-statement macros is
#define FUNC() do { statement1; statement2; } while(0)
That way even if(b) FUNC(); does what the caller thinks.
There has been a discussion a few years ago which led to a change in the MISRA rules concerning this; MISRA does not recommend the "do" strategy any longer, because they say one should always use curly braces, as in if(b) { FUNC(); } which would handle unprotected multi-statement macros gracefully (and prevent bugs like the Apple certificate goto screw-up). Instead, a do{... would camouflage the failure to use braces.
I think I personally still side on the doside, if only because I know it.
CERT recommends the technique as well.
Related
https://florian.github.io/xor-trick/
There's a part in the article that reads (the first step operates on (x,y))
x ^= y # => (x ^ y, y)
y ^= x # => (x ^ y, y ^ x ^ y) = (x ^ y, x)
x ^= y # => (x ^ y ^ x, x) = (y, x)
I would have thought second line would be
y ^= x # =>(x ^ y ^ x, y ^ x) = (y, y ^ x)
then third line
x ^= y # => (y, y ^ x ^ y) = (y, x)
If that part of the article is correct and I'm in error about how it should work, any tips about what I'm missing?
Later,the article has
If we analyze the individual bits in u ^ v, then every 0 means that
the bit had the same value in both u and v. Every 1 means that the
bits differed.
Using this, we find the first 1 in u ^ v, i.e. the first position i
where u and v have to differ. Then we partition A as well as the
numbers from 1 to n according to that bit. We end up with two
partitions, each of which contains two sets:
Partition 0
The set of all values from 1 to n where the i-th bit is 0
The set of all values from A where the i-th bit is 0
Partition 1
The set of all values from 1 to n where the i-th bit is 1
The set of all values from A where the i-th bit is 1
Since u and v differ in position i, we know that they have to be in
different partitions.
Let me see if I get this. Partition 0 contains one of u or v, we don't know which. Partition 1 contains v or u, whichever wasn't in Partition 0. We operate each with ^u^v to get u and v respectively. So yes, the array has to be partitioned into two parts, and I think I understand the basis for the partition and why it has to be done (to later isolate u and v after operating ^u^v).
But why is it noted that each partition contains two sets? I'm assuming the ith bit is the first "1" bit in u^v. It wouldn't be enough to partition the array into two parts, one partition with ith bit being 0 and one partition with ith bit being 1? 🤔 What's the significance of the set of all values from 1 to n where th i-th bit is 0, or 1, respectively?
Or is it not significant that the partitions each have two sets, and the sets are just a leftover byproduct of how the partitions were determined?
Thanks for any answers.
You ask two related questions, I'll answer both:
First, in this XOR-int-swap code the commented x and y do not stand for the current variable values, rather they stand for the original values of those variables
x ^= y # => (x ^ y, y)
y ^= x # => (x ^ y, y ^ x ^ y) = (x ^ y, x)
x ^= y # => (x ^ y ^ x, x) = (y, x)
The first operation x ^= y sets x to original_x ^ original_y.
The second operation y ^= x sets y to original_y ^ original_x ^ original_y, which is just original_x.
The third operation x ^= y sets x to original_x ^ original_y ^ original_x, which becomes original_y.
The second part is about the question How can we use XOR to find two missing values in a range/sequence of numbers?.
Your understanding is correct that by using XOR on both the sequence (without missing numbers) and the array (with two missing numbers), our final result is just the XOR of the two missing numbers, since doing XOR with the same number twice cancels itself out.
Since the two missing numbers have to be different numbers, they will differ at some index i, at which their XOR will be 1.
Once we have this index we can just run the algorithm that checks for a single missing number, simply by partitioning the numbers on whether they have the i-th bit set or not. And because the two numbers differ on the i-th bit, each partition will have exactly one of the missing numbers.
why is it noted that each partition contains two sets
The word 'set' might be the confusing part here, what is meant is "a set of numbers that was XORed with", the general idea is that:
we create a variable a = 0
we XOR a with all numbers in the sequence that have the i-th bit set (this is the first 'set')
we XOR a with all numbers in our array that have the i-th bit set (this is the second 'set')
Again the XOR operations cancel each other out, just for the one missing number we executed the XOR only once, so a is 0 ^ missing_number, which is missing_number.
Find a detailed explanation of this method in this answer here.
I'm only a casual user of C, when programming for micros like Arduino, but I'm interested in bettering my understanding of the vernacular.
I know that you can shorthand things like x = x % 10 to x %= 10, and x = x + 1 to x += 1. But I couldn't wrap my head around compounding both parts of this:
x = (x + 1) % 10
If that's possible, what does it look like?
(x += 1) %= 10 ? That seems... if not wrong, then confusing.
The expression (x += 1) %= 10 is not legal in C. The result of an assignment operator, whether = or one of the compound assignment operators, is not a lvalue. Loosely speaking, this means it can't appear on the left side of an assignment.
That statement would have to be broken up in two parts:
x += 1;
x %= 10;
As an aside, (x += 1) %= 10 is valid in C++.
Just try x += 1; x %= 10; as an alternative, it will work, but it is not equivalent to the first expression. You cannot wrap both in a single expression[1] as
x op= expression;
means
x = x op (expression); /* look at the parenthesis */
and that forces the evaluation of the expression first. The only case in which
x = (x op1 a) op2 b;
could be converted to an op-assign operation is if the operators are associative and the expression can be converted to:
x = x op1 (a op2 b);
(or if op2 has higher precedence than op1, which means the evaluation order is as above) and then
x op1= a op2 b;
would be possible.
Examples
x = x + a + b; ==> x += a + b; /* this implies a different order of evaluation */
x = x + a * b; ==> x += a * b;
x = x + a % b; ==> x += a % b; /* % has higher precedence than + */
Note [1]: well, you can, but using another operator, the , comma operator, you can convert it to x += 1, x %= 10;
The increment operator modifies the original value like,
int i = 5;
i++;
printf("%d",i); //prints 6
but the bit operator does not, example,
int x = 5;
x<<1;
printf("%d",x);//should print 10 but outputs the original value i.e. 5
x << 1 is analogous to operations like x * 2. If you don't store the result anywhere, it is just discarded and the line may just get omitted entirely by an optimizing compiler.
If you want to store the result of an operation like that back into x, you have options like:
x = x * 2;
x *= 2;
The << operator is the same:
x = x << 1;
x <<= 1;
Often and often I felt some of the parentheses around arguments in macro definitions were redundant. It’s too inconvenient to parenthesize everything. If I can guarantee the argument needs not be parenthesized, can I omit the parentheses? Or is parenthesizing them all highly recommended?
I came up with this question when I wrote:
#define SWAP_REAL(a, b, temp) do{double temp = a; a = b; b= temp;}while(0)
I think that if an argument appears as an l-value in the macro, the parentheses can be omitted because that means the argument appears with no other operation.
My reasoning is:
The associative priority of assignment symbols is merely higher than comma’s.
You cannot confuse the compiler into thinking that your argument is an expression with a comma in it. For example, SWAP(a, b, b) will not be interpreted successfully as
do{double temp = a, b; a, b = b; b= temp;}while(0)
which can pass compilation.
Am I right? Can anyone give me a counter-example?
In the following example,
#define ADD(a, b) (a += (b))
I think the argument a needn’t be parenthesized. And in this specific case, neither needs the argument b, right?
#JaredPar:
#include <stdio.h>
#define ADD(a, b) (a += (b))
int main(){
int a = 0, b = 1;
ADD(a; b, 2);
return 0;
}
This cannot be compiled successfully on my VS2010. Error C2143: syntax error : missing ')' before ';'
In a nutshell, you don’t need to parenthesize the arguments having appeared as an l-value in the macro, but you are highly recommended to parenthesize them all.
Rules of Macros:
DO NOT make macros with side effects!
As for macros with no side effect, just parenthesize all the arguments without second thought!
As for macros with side effect, stop being obsessive! Parenthesize them all! TnT
Here is one case where it makes a demonstrable difference
ADD(x;y, 42)
With parens this leads to a compilation error but without it leads to code that compiles.
(x;y) += 42; // With parens errors
x;y += 42; // Without parens compiles
This may look like a silly example but it's possible combining macros together can easily lead to strange code expressions like the above.
Why take the chance here? It's just 2 characters
It's unsafe to omit if you use any operator that isn't lowest precedence in your expression. I believe that would be comma.
a op b where op is some operator like +, * etc. will always bind wrong if a contains an expression of low precedence like 1 || 2.
Note I'm not claiming it's safe in those cases. There are more creative ways to break macros. By the way, don't use macros with side effects in the first place. More generally, don't use macros as functions. (See, e.g., Effective C++).
There are macros where you're concatenating elements to make a string (perhaps using the # operator), or building identifiers out of macro arguments using the ## operator. In such cases, you don't parenthesize the arguments.
Also, I think that when the macro arguments are themselves passed as function arguments, then you don't absolutely have to parenthesize them:
#define CALLOC(s, n) calloc(s, n)
You can play fiendish games calling such a macro (CALLOC({3, 4})), but you get what you deserve (a compilation error) — I'm not aware of a way of calling that macro that would work if instead of the macro you wrote the same arguments as a direct call to calloc().
However, if you are using the arguments in most arithmetic expressions, then you do need to wrap them in parentheses:
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
Obviously, if you invoke it with arguments with side effects, then you get what you get. But the arguments won't be misinterpreted as they could be if you wrote:
#define MIN(x, y) x < y ? x : y
and then invoked it as:
MIN(x = 3 * y + 1, y = 2 * x - 2);
The comment by Moon suggests a SWAP_INT macro.
The following code using that macro compiles cleanly when compiled using default options, but fails to compile with -DWITH_PARENTHESES set.
#include <stdio.h>
#ifdef WITH_PARENTHESES
#define SWAP_INT(a, b) do { int temp = (a); (a) = (b); (b) = temp; } while (0)
#else
#define SWAP_INT(a, b) do { int temp = a; a = b; b = temp; } while (0)
#endif
int main(void)
{
int p = 319;
int q = 9923;
int x = 23;
int y = 300;
printf("p = %8d, q = %8d, x = %8d, y = %8d\n", p, q, x, y);
SWAP_INT(p, q); // OK both ways
SWAP_INT(x, y); // OK both ways
printf("p = %8d, q = %8d, x = %8d, y = %8d\n", p, q, x, y);
SWAP_INT(x /= y, p *= q); // Compiles without parentheses; fails with them
printf("p = %8d, q = %8d, x = %8d, y = %8d\n", p, q, x, y);
return 0;
}
The output:
p = 319, q = 9923, x = 23, y = 300
p = 9923, q = 319, x = 300, y = 23
p = 41150681, q = 13, x = 0, y = 3165437
That isn't a safe or effective way of swapping integers — the macro without the parentheses is not a good idea.
JFTR: when compiled without -DWITH_PARENTHESES, the line for the macro with the expressions is inscrutable:
do { int temp = x /= y; x /= y = p *= q; p *= q = temp; } while (0);
Normally, a swap macro expects two variable names — or array elements, or structure or union members, or any mix of these. It does not expect to be given arbitrary expressions. The parentheses ensure that the assignment to x /= y (which is not an lvalue) fails; without the parentheses, the expression is interpreted, but it isn't anything like what was intended (if, indeed, anything could be intended when 'swapping' two expressions like that).
Hey I have been having trouble with a C program. The program I have to write simulates the operation of a VAX computer. I have to take in 2 variables x and y to generate z.
within that there are two functions, the first
Sets Z to 1 where each bit position of y = 1
2nd sets z to 0 where each bit position of y = 1
I'm not asking for someone to do this for me, I just need an explanation on how this is carried out as I have a bare bones of the two functions that I need. I was thinking of something like this but I don't know if it's right at all.
#include<stdio.h>
int main()
{
int x1 = 1010;
int y1 = 0101;
bis(x1, y1);
bic(x1, y1);
}
/* BIT SET function that sets the result to 1 wherever y = 1 */
int bis (int x, int y)
{
int z = x & y;
int result = ?;
printf("BIT SET: \n\n", result);
return result;
}
/* BIT CLEAR function that sets result to 0 wherever y = 1 */
int bic(int x, int y)
{
int z = x & y;
int result = ?;
printf("BIT CLEAR:\n\n ", result);
return result;
}
Apologies for the poor naming conventions. Am I anyway on the right track for this program?
Let's look at bitset() first. I won't post C code, but we can solve this on paper as a start.
Say you have your integers with the following bit patterns: x = 1011 and y = 0101. (I'm changing your example numbers. And, incidentally, this is not how you would define two integers having these bit patterns, but right now we're focusing on the logic.)
If I am understanding correctly, when you call bitset(x, y), you want the answer, Z, to be 1111.
x = 1011
y = 0101
^ ^-------- Because these two bits have the value 1, then your answer also
has to set them to 1 while leaving the other bits in x alone.
Well, which bitwise operation will accomplish this? You have AND (&), OR (\), XOR (^), and COMPLEMENT (~).
In this case, you are ORing the two values. Looking at the following truth table:
x 1 0 1 1
y 0 1 0 1
-----------------
(x OR y) 1 1 1 1
Each bit in the last row is given by ORing that column in x and y. So (1 OR 0) = 1, (0 OR 1) = 1, (1 OR 0) = 1, (1 OR 1) = 1
So now you can write a C function bitset(x, y), ORs x and y, and returns the result as Z.
What bitwise operator - and you can do it in multiple steps with multiple operators - would you use to clear the bits?
x 1 0 1 1
y 0 1 0 1
-------------------------------------------
(SOME OPERATONS INVOLVING x and y) 1 0 1 0
What would those logical operators (from the list above) be? Think about the "and" and "complement" operators.
Good luck on your hw!
Bonus: A quick primer on expressing integers in C.
int x = 1337 creates an integer and gives it the value 1337. If you said x = 01337, x WILL NOT have the value "1337" like you might expect. By placing the 0 in front of the number, you're telling C that that number is in octal (base 8). The digits "1337", interpreted in base 8, is equivalent to decimal (base 10) 735. If you said x = 0x1337 then you are expressing the number in base 16, as a hexadecimal, equivalent to 4919 in base 10.
Nope... what you have there will and together two integers. One of which is 1010 (base10), and the other of which is 101 (base 8 - octal -> 65 base 10).
First you'll want to declare your constants as binary (by prefixing them with 0b).
Second, you'll want to out put them (for your instructor or TA) as a binary representation. Check out this question for more ideas