how does CF(Carry flag) get set according to the computation t = a-b where a and b are unsigned integers - bit-manipulation

I'm new to x64-64, just a question on how does CF get set? I was reading a textbook which says:
CF: Carry flag is used when most recent operation generated a carry out of the most significant bit. Used to detect overflow for unsigned operations.
I have two questions:
Q1-suppose we used one of the add instructions to perform the equivalent of the C assignment t = a+b, where variables a, b, and t are integers (only 3 bits for simplicity), so for 011(a) + 101(b) = 1000 = 000, since we have a carry out bit 1 in the fourth digit, so CF flag will be set to 1, is my understanding correct?
Q2-if my understanding in Q1 is true, and suppose we used one of the sub instructions to perform the equivalent of the C assignment t = a-b, where a, b, and t are unsigned integers, since a, b are unsigned, we can't actually do a+(-b), and I don't get how we can make 011(a) - 101(b) carry out of the most significant bit?

The carry flag is often called "borrow" when performing a subtraction. After a subtraction, it set if a 1 had to be borrowed from the next bit (or would have been borrowed if you used the grade-school subtraction method). The borrow flag is like a -1 in that bit position:
011 -1 211
- 101 -> - 101
----- -----
B 110
You can get the same result by adding a zero to the arguments, and then the carry or borrow will be the high bit of the result:
0011 - 0101 = 0011 + (-0101) = 0011 + 1011 = 1110

Related

What does 0b1 mean in C++?

I came across a part of code that I cannot understand.
for (unsigned int i = (x & 0b1); i < x; i+= 2)
{
// body
}
Here, x is from 0 to 5.
What is meant by 0b1? and what would be the answers for eg: (0 & 0b1), (4 & 0b1) etc?
0b... is a binary number, just like 0x... is hex and 0... is octal.
Thus 0b1 is same as 1.
1b0 is illegal, the first digit in those must always be 0.
As previous answers said, it is the binary representation of the integer number 1, but they don't seem to have fully answered your question. This has a lot of layers so I'll briefly explain each.
In this context, the ampersand is working as a bitwise AND operator. i & 0b1 is (sometimes) a faster way of checking if an integer is even as opposed to i % 2 == 0.
Say you have int x = 5 and you'd like to check if it's even using bitwise AND.
In binary, 5 would be represented as 0101. That final 1 actually represents the number 1, and in binary integers it's only present in odd numbers. Let's apply the bitwise AND operator to 5 and 1;
0101
0001
&----
0001
The operator is checking each column, and if both rows are 1, that column of the result will be 1 – otherwise, it will be 0. So, the result (converted back to base10) is 1. Now let's try with an even number. 4 = 0100.
0100
0001
&----
0000
The result is now equal to 0. These rules apply to every single integer no matter its size.
The higher-level layer here is that in C, there is no boolean datatype, so booleans are represented as integers of either 0 (false) or any other value (true). This allows for some tricky shorthand, so the conditional if(x & 0b1) will only run if x is odd, because odd & 0b1 will always equal 1 (true), but even & 0b1 will always equal 0 (false).

Generate a list of binary numbers where n bits are set to 1

I want to generate a list of binary numbers with m digits, where n bits are set to 1 and all others are set to 0. For example, let's say m is 4. I want to generate a list of binary numbers with 4 bits. Of the 16 numbers, 6 of them have 2 bits set to 1, with the others being all 0s.
0000
0001
0010
0011 <--
0100
0101 <--
0110 <--
0111
1000
1001 <--
1010 <--
1011
1100 <--
1101
1110
1111
I want to generate a list for any m bits with n bits set to 1, at the very least for the case of where n = 2. But I'm not sure what process to follow. I could of course brute-force it and generate all numbers that are m bits then check each one individually, but for a larger number of bits that could take a while. I feel like there must be a neater mathematical trick to find out the answer.
I'd appreciate any pointers of where to start. I don't mind if answers are in pseudocode or any language, so long as they're clear.
The XY problem
I'm trying to solve a chess problem, where there are two pieces on the board. First I'm trying to generate all the valid combinations of two pieces on the board, which I'm planning to do by treating the chessboard as a 64-bit binary number (0000 0000 0000 0000 .. 0011) where an on-bit is a piece. To do this I need to find an elegant way to generate the list of binary numbers.
Edit: I've tried implementing the naive algorithm in Python just for demonstration. It's taking an awful long while to execute on my VS Code for m = 64, so definitely isn't the best solution:
n = 2
m = 64
combos = []
for i in range(2 ** m):
bin_s = str(format(i, f'0{m}b'))
if bin_s.count('1') == n:
combos.append(bin_s)
for c in combos:
print(c)
print(f"There are {len(combos)} combinations")
This is called lexicographically next permutation, which is available in many bit hacking sites.
https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
Starting with x = 0b000000111 e.g. for 3 bits, one iterates until x & (1 << m) (or there's an overflow if m == word_size).
uint64_t next(uint64_t v) {
uint64_t t = v | (v - 1); // t gets v's least significant 0 bits set to 1
// Next set to 1 the most significant bit to change,
// set to 0 the least significant ones, and add the necessary 1 bits.
return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
}
uint64_t v = 15; // 4 bits
do {
my_func(v);
if (v == 0xf000000000000000ull) {
break;
}
v = next(v);
} while (true);
Use https://docs.python.org/3/library/itertools.html#itertools.combinations to produce the set of indexes at which you have a 1. Turning that into a binary number is straightforward.
If you want this in another language, the documentation has native Python code to solve the problem.

Need help to find a bit wise operation to fit my case study

I want to do bit operation between operand A and operand B so that result has the following bits.
Note: 1 = set , 0 = clear so
A = 1010
B = 0011
Result= 0011
That is, I want to inverse A bit if A and B are different, keep A bit if A and B are the same.
Some more examples:
Original=Set |Clear|Set|Clear
Latest =Clear|Clear|Set|Set
Result =Clear|Clear|Set|Set
A=0001
B=1000
Result=1000
You are looking to retain B in all cases. As your truth table shows. You go through all possibilities, and for all of them you get B back....

Why 10^1 is 11?

I am currently learning C++. I was trying to compute power of an integer using the expression:
val=10^1;
Instead of expected answer 10, the result was 11. I have fixed the problem by using pow function of math.h library but I am wondering why this statement is giving me the wrong result.
No! Do you think that is the power? Don't forgot this (In C++ and some of the programming languages):
Be sure to read this:
Operators (cplusplus)
Bitwise operation (wikipedia)
A bitwise XOR takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits. The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1. In this we perform the comparison of two bits, being 1 if the two bits are different, and 0 if they are the same. For example:
0101 (decimal 5)
XOR 0011 (decimal 3)
= 0110 (decimal 6)
The bitwise XOR may be used to invert selected bits in a register (also called toggle or flip). Any bit may be toggled by XORing it with 1. For example, given the bit pattern 0010 (decimal 2) the second and fourth bits may be toggled by a bitwise XOR with a bit pattern containing 1 in the second and fourth positions:
0010 (decimal 2)
XOR 1010 (decimal 10)
= 1000 (decimal 8)
This technique may be used to manipulate bit patterns representing sets of Boolean states.
Source: Wikipedia
That's the bitwise exclusive-or operator, not power. In binary:
10 = 1010
1 = 0001
val= 1011 = 11 in decimal
In C and C++, 10^1 is 10 XOR 1, not 10 to the power of 1.
^ is the binary XOR operator in C++:
10 ^ 1 =
00001010
^ 00000001
= --------
00001011 = 11
Because ^ is the exclusive or operator and not the exponentiation operator. Basically, because the last bit of 10 in binary is 0, by applying exclusive or of 1 the last bit gets converted to 1 because it is different than 0.
Because in C++ there is no power operator: ^ is a XOR.
1010 is 10102 in binary; 110 is 00012. XORing them together gives 10112, which is 1110.
If you would like to obtain 10n, use the pow function from <cmath> header:
val=pow(10, 1);

CRC calculation by example

I'd like to confirm whether I grasped the concept of CRC calculations correctly. I'll provide two examples, the first is calculating the remainder using normal subtraction, the second uses this weird XOR stuff.
Data bits: D = 1010101010.
Generator bits: G = 10001.
1) Subtraction approach to calculate remainder:
10101010100000
10001|||||||||
-----|||||||||
10001|||||||
10001|||||||
-----|||||||
000000100000
10001
-----
1111
R = 1111.
2) XOR approach:
10101010100000
10001|||||||||
-----|||||||||
10001|||||||
10001|||||||
-----|||||||
00000010000|
10001|
------
000010
R = 0010.
Appending 1111 at the end does not satisfy the need since
10927 % 17 != 0
.
Note that as per the definition, the division should be modulo division as it is based upon modulo mathematics.
Both answers are correct. =)
(To recheck the first answer:
10101010100000 (binary) mod 10001 (binary)
= 10912 (decimal) mod 17 (decimal)
= 15 (decimal)
= 1111 (binary).)
Subtraction is wrongly done. In binary modulo, subtraction, addition, division, and multiplication are the same. So, XOR is correct.