What does a bitwise AND do with no value infront of it? - bit-manipulation

I am using Verilog. Say you have the term:
& A
or
~& A
What does this do? Does it just compare it to an all empty array?

It performs a bitwise operation on all bits of the operand
e.g.:
//let x = 4’b1010
&x //equivalent to 1 & 0 & 1 & 0. Results in 1’b0
|x //equivalent to 1 | 0 | 1 | 0. Results in 1’b1
^x //equivalent to 1 ^ 0 ^ 1 ^ 0. Results in 1’b0
More about verilog operators: https://web.engr.oregonstate.edu/~traylor/ece474/beamer_lectures/verilog_operators.pdf

Related

What does 'if((mask | u)==u)' mean?

This is the recurrence relation of maximum sum subset problem.
The complete code is:
if ((mask | u) == u)
dp[u] = max(max(0, dp[u ^ mask] + array[I], dp[u]);
What does exactly mean the following if-statement?
if((mask | u) == u)
Thank you in advance!
It means: “Are all bits of mask in u”.
So if there is a bit in mask not in u this test returns false.
For instance with mask=0b001 and u=0b011 it returns true. But with mask=0b101 and u=0b011 it returns false because the third bit of mask is not set in u.
Binary OR for binary values A, B evaluates as (1) if either A = 1 or B = 1. These bitwise operations extend to strings of binary digits. In C/C++, that's most commonly expressed as integral types.
OR | A = 0 | A = 1 |
-----------------------
B = 0 | (0) | (1) |
-----------------------
B = 1 | (1) | (1) |
-----------------------
(forgive the ASCII art - more concise illustrations and links are here)
mask = {m(n - 1), m(n - 2), .., m(1), m(0)} : (n) binary digits (bits) m(i)
u = {u(n - 1), u(n - 2), .., u(1), u(0)} : (n) binary digits (bits) u(i)
Let's consider (m(i) | u(i)) == u(i) for: i = {0, .., n - 1} ; should any of these bit-wise comparisons be false, then the expression ((mask | u) == u) evaluates as false.
From the OR table we can conclude that the expression is false if and only if m(i) = 1 and u(i) = 0. That is: m(i) | u(i) == (1) OR (0) == (1) which does not equal u(i) == 0
A more concise way of expressing the issue is that if mask has a bit at a position (i) set to (1), and u has a bit at the same position cleared to (0), then (mask | u) cannot equal u.

Odd bit operator in the increment statement of a for loop [duplicate]

This question already has answers here:
meaning of (number) & (-number)
(4 answers)
Closed 8 years ago.
Given this for loop:
for(++i; i < MAX_N; i += i & -i)
what is it supposed to mean? What does the statement i += i & -i accomplish?
This loop is often observed in binary indexed tree (or BIT) implementation which is useful to update range or point and query range or point in logarithmic time. This loop helps to choose the appropriate bucket based on the set bit in the index. For more details, please consider to read about BIT from some other source. In below post I will show how does this loop help to find the appropriate buckets based on the least significant set bits.
2s complementary signed system (when i is signed)
i & -i is a bit hack to quickly find the number that should be added to given number to make its trailing bit 0(that's why performance of BIT is logarithmic). When you negate a number in 2s complementary system, you will get a number with bits in inverse pattern added 1 to it. When you add 1, all the less significant bits would start inverting as long as they are 1 (were 0 in original number). First 0 bit encountered (1 in original i) would become 1.
When you and both i and -i, only that bit (least significant 1 bit) would remain set and all lesser significant (right) bits would be zero and more significant bits would be inverse of original number.
Anding would generate a power of 2 number that when added to number i would clear the least significant set bit. (as per the requirement of BIT)
For example:
i = 28
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
*
-i
+---+---+---+---+---+---+---+---+
| 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
I I I I I S Z Z
Z = Zero
I = Inverted
S = Same
* = least significant set bit
i & -i
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
Adding
+---+---+---+---+---+---+---+---+
| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
x
x = cleared now
Unsigned (when i is unsigned)
It will work even for 1s complementary system or any other representation system as long as i is unsigned for the following reason:
-i will take value of 2sizeof(unsigned int) * CHAR_BITS - i. So all the bits right to the least significant set bit would remain zero, least significant bit would also remain zero, but all the bits after that would be inverted because of the carry bits.
For example:
i = 28
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
*
-i
0 1 1 1 1 1 <--- Carry bits
+---+---+---+---+---+---+---+---+
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
- | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
----------------------------------------
+---+---+---+---+---+---+---+---+
| 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
I I I I I S Z Z
Z = Zero
I = Inverted
S = Same
* = least significant set bit
i & -i
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+---+---+---+---+---+---+---+---+
Adding
+---+---+---+---+---+---+---+---+
| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+
x
x = cleared now
Implementation without bithack
You can also use i += (int)(1U << __builtin_ctz((unsigned)i)) on gcc.
Live example here
A non obfuscated version for the same would be:
/* Finds smallest power of 2 that can reset the least significant set bit on adding */
int convert(int i) /* I purposely kept i signed as this works for both */
{
int t = 1, d;
for(; /* ever */ ;) {
d = t + i; /* Try this value of t */
if(d & t) t *= 2; /* bit at mask t was 0, try next */
else break; /* Found */
}
return t;
}
EDITAdding from this answer:
Assuming 2's complement (or that i is unsigned), -i is equal to ~i+1.
i & (~i + 1) is a trick to extract the lowest set bit of i.
It works because what +1 actually does is to set the lowest clear bit,
and clear all bits lower than that. So the only bit that is set in
both i and ~i+1 is the lowest set bit from i (that is, the lowest
clear bit in ~i). The bits lower than that are clear in ~i+1, and the
bits higher than that are non-equal between i and ~i.

XOR operation in C++

How does the XOR logical operator work on more than two values?
For instance, in an operation such as 1 ^ 3 ^ 7?
0 0 0 1 // 1
0 0 1 1 // 3
0 1 1 1 // 7
__
0 1 0 1 // 5
for some reason yields 0 1 0 1, where as it should have, as I thought, yielded: 0 1 0 0, since XOR is only true when strictly one of the operands is true.
Because of the operator precedence and because the xor is a binary operator, which in this case is left-to-right.
First 1 ^ 3 is evaluated
0 0 0 1 // 1
0 0 1 1 // 3
-------
0 0 1 0 // 2
The result is 2, then this number is the first operand of the last xor operation (2 ^ 7)
0 0 1 0 // 2
0 1 1 1 // 7
-------
0 1 0 1 // 5
The result is 5.
1 ^ 3 ^ 7 is not a function of three arguments, it is: (1 ^ 3) ^ 7 which equals 2 ^ 7 which equals 5.
Though actually this ^ operator is associative: each bit in the result will be set if and only if an odd number of the operands had the bit set.
XOR works bitwise, XORing each position separately
XOR is commutative, so a^b = b^a
XOR is associative, so (a^b)^c = a^(b^c)
Using this, a human can count the number of ones in a given position and the result bit is set exactly for an odd number of ones in the given position of the operands.
Counting ones yields (0101)binary=5
The expression is parsed as (1 ^ 3) ^ 7 so you first get
0001 ^ 0011
which is 0010. The rest is
0010 ^ 0111
which is 0101
^ is a binary operator. It doesn't work on all three numbers at once, i.e. it's (1^3)^7, which is:
1 ^ 3 == 2
2 ^ 7 == 5

what this "if(k.c[3] & c)" part of code doing?

#include<stdio.h>
#include<iostream.h>
main()
{
unsigned char c,i;
union temp
{
float f;
char c[4];
} k;
cin>>k.f;
c=128;
for(i=0;i<8;i++)
{
if(k.c[3] & c) cout<<'1';
else cout<<'0';
c=c>>1;
}
c=128;
cout<<'\n';
for(i=0;i<8;i++)
{
if(k.c[2] & c) cout<<'1';
else cout<<'0';
c=c>>1;
}
return 0;
}
if(k.c[2] & c)
That is called bitwise AND.
Illustration of bitwise AND
//illustration : mathematics of bitwise AND
a = 10110101 (binary representation)
b = 10011010 (binary representation)
c = a & b
= 10110101 & 10011010
= 10010000 (binary representation)
= 128 + 16 (decimal)
= 144 (decimal)
Bitwise AND uses this truth table:
X | Y | R = X & Y
---------
0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1
See these tutorials on bitwise AND:
Bitwise Operators in C and C++: A Tutorial
Bitwise AND operator &
A bitwise operation (AND in this case) perform a bit by bit operation between the 2 operands.
For example the & :
11010010 &
11000110 =
11000010
Bitwise Operation in your code
c = 128 therefore the binary representation is
c = 10000000
a & c will and every ith but if c with evert ith bit of a. Because c only has 1 in the MSB position (pos 7), so a & c will be non-zero if a has a 1 in its position 7 bit, if a has a 0 in pos bit, then a & c will be zero. This logic is used in the if block above. The if block is entered depending upon if the MSB (position 7 bit) of the byte is 1 or not.
Suppose a = ? ? ? ? ? ? ? ? where a ? is either 0 or 1
Then
a = ? ? ? ? ? ? ? ?
AND & & & & & & & &
c = 1 0 0 0 0 0 0 0
---------------
? 0 0 0 0 0 0 0
As 0 & ? = 0. So if the bit position 7 is 0 then answer is 0 is bit position 7 is 1 then answer is 1.
In each iteration c is shifted left one position, so the 1 in the c propagates left wise. So in each iteration masking with the other variable you are able to know if there is a 1 or a 0 at that position of the variable.
Use in your code
You have
union temp
{
float f;
char c[4];
} k;
Inside the union the float and the char c[4] share the same memory location (as the property of union).
Now, sizeof (f) = 4bytes) You assign k.f = 5345341 or whatever . When you access the array k.arr[0] it will access the 0th byte of the float f, when you do k.arr[1] it access the 1st byte of the float f . The array is not empty as both the float and the array points the same memory location but access differently. This is actually a mechanism to access the 4 bytes of float bytewise.
NOTE THAT k.arr[0] may address the last byte instead of 1st byte (as told above), this depends on the byte ordering of storage in memory (See little endian and big endian byte ordering for this)
Union k
+--------+--------+--------+--------+ --+
| arr[0] | arr[1] | arr[2] | arr[3] | |
+--------+--------+--------+--------+ |---> Shares same location (in little endian)
| float f | |
+-----------------------------------+ --+
Or the byte ordering could be reversed
Union k
+--------+--------+--------+--------+ --+
| arr[3] | arr[2] | arr[1] | arr[0] | |
+--------+--------+--------+--------+ |---> Shares same location (in big endian)
| float f | |
+-----------------------------------+ --+
Your code loops on this and shifts the c which propagates the only 1 in the c from bit 7 to bit 0 in one step at a time in each location, and the bitwise anding checks actually every bit position of the bytes of the float variable f, and prints a 1 if it is 1 else 0.
If you print all the 4 bytes of the float, then you can see the IEEE 754 representation.
c has single bit in it set. 128 is 10000000 in binary. if(k.c[2] & c) checks if that bit is set in k.c[2] as well. Then the bit in c is shifted around to check for other bits.
As result the program is made to display the binary representation of float it seems.

how to calculate bitwise OR using AND, XOR and shift?

The question seems pretty well formulated
I have a virtual machine which implements only AND, XOR, SHL and SHR, yet I have to do a "OR 0x01" operation.
First of all having a correct bitwise computation for the following two variables is sufficient, because they cover all combinations:
A=0101
B=0011
We want
0101
0011
A or B
0111
for xor we get
0101
0011
A xor B
0110
for and we get
0101
0011
A and B
0001
so if we connect them with an xor we are done.
(A xor B) xor (A and B)
I would just start with
a xor b = ((not a) and b) or (a and (not b))
and unleash some boolean algebra on that until it looks like
a or b = <expression using only and, xor>
Admittedly, this is probably more work to actually do than going the "try every conceivable bit combination" route, but then you did ask for homework solution ideas. :)
The truth table as summarized on Wikipedia here and gasp, basic CS 101 stuff, De Morgan's Law....
AND
0 & 0 0
0 & 1 0
1 & 0 0
1 & 1 1
OR
0 | 0 0
0 | 1 1
1 | 0 1
0 | 0 1
XOR
0 ^ 0 0
0 ^ 1 1
1 ^ 0 1
1 ^ 1 0
A Shift Left involves shifting the bits across from right to left, suppose:
+-+-+-+-+-+-+-+-+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
|0|0|0|0|0|1|0|0| = 0x4 hexadecimal or 4 decimal or 100 in binary
+-+-+-+-+-+-+-+-+
Shift Left by 2 places becomes
+-+-+-+-+-+-+-+-+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
|0|0|0|1|0|0|0|0| = 0x10 hexadecimal or 16 decimal or 10000 in binary
+-+-+-+-+-+-+-+-+
Shift Right by 1 places becomes
+-+-+-+-+-+-+-+-+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0| = 0x8 hexadecimal or 8 decimal or 1000 in binary
+-+-+-+-+-+-+-+-+
Then it is a matter of combining the bit-wise operations according to the truth table above...
I would just expand DeMorgan's law: A or B = not(not A and not B). You can compute not by XORing with all 1 bits.