Skip to main content
added 891 characters in body
Source Link
sudhackar
  • 2.7k
  • 1
  • 11
  • 28

In signed values the MSB dictates the sign of the number - a set MSB means -ve and unset means a +ve number.

Now if v7 is a signed value - we can see the change in values with this python snippet

In [9]: x = 0xabcdef1234567890

In [10]: ctypes.c_uint64(x & 0x7FFFFFFFFFFFFFFF)
Out[10]: c_ulong(3156441775323117712)

In [11]: (ctypes.c_int64(x & 0x7FFFFFFFFFFFFFFF).value)
Out[11]: 3156441775323117712

In [12]: ctypes.c_int64(x).value
Out[12]: -6066930261531658096

With the MSB cleared the signed and unsigned values of the result is same.

In [13]: (ctypes.c_int64(x | 0x8000000000000000).value)
Out[13]: -6066930261531658096

In [14]: (ctypes.c_uint64(x | 0x8000000000000000).value)
Out[14]: 12379813812177893520

In [15]: x
Out[15]: 12379813812177893520

With the MSB set - the number stays as is if it was a signed negative earlier.

In signed values the MSB dictates the sign of the number - a set MSB means -ve and unset means a +ve number.

Now if v7 is a signed value - we can see the change in values with this python snippet

In [9]: x = 0xabcdef1234567890

In [10]: ctypes.c_uint64(x & 0x7FFFFFFFFFFFFFFF)
Out[10]: c_ulong(3156441775323117712)

In [11]: (ctypes.c_int64(x & 0x7FFFFFFFFFFFFFFF).value)
Out[11]: 3156441775323117712

In [12]: ctypes.c_int64(x).value
Out[12]: -6066930261531658096

With the MSB cleared the signed and unsigned values of the result is same.

In [13]: (ctypes.c_int64(x | 0x8000000000000000).value)
Out[13]: -6066930261531658096

In [14]: (ctypes.c_uint64(x | 0x8000000000000000).value)
Out[14]: 12379813812177893520

In [15]: x
Out[15]: 12379813812177893520

With the MSB set - the number stays as is if it was a signed negative earlier.

Source Link
sudhackar
  • 2.7k
  • 1
  • 11
  • 28

When you see such masks - remember these key rules for bitwise arithmetic Assume X is unknown, & is bitwise AND, | is bitwise OR

  • X & 1 = X
  • X & 0 = 0
  • X | 0 = X
  • X | 1 = 1

Now look at the mask and its operation. In this case

v7 | 0x8000000000000000LL

The mask

In [1]: 0x8000000000000000 == 1 << 63
Out[1]: True

So in this case a 64 bit number - with the most significant bit (MSB) set and all other 0s

index - 63 62 61 ... 2 1 0
bits  - 1  0  0  ... 0 0 0

The operation here is | - the bitwise OR We don't know v7 - we can assume it to be X. For individual bits X_i for i index

index - 63   62   61   ... 2   1   0
bitsX - X_63 X_62 X_61 ... X_2 X_1 X_0

When bitwise OR is done -

index - 63   62   61   ... 2   1   0
bitsX - X_63 X_62 X_61 ... X_2 X_1 X_0
mask  - 1    0    0    ... 0   0   0

With the rules mentioned above - we can operate X | 1 = 1

index - 63   62   61   ... 2   1   0
bitsX - X_63 X_62 X_61 ... X_2 X_1 X_0
mask  - 1    0    0    ... 0   0   0
result- 1 

for the rest unknown bits X | 0 = X

index - 63   62   61   ... 2   1   0
bitsX - X_63 X_62 X_61 ... X_2 X_1 X_0
mask  - 1    0    0    ... 0   0   0
result- 1    X_62 X_61 ... X_2 X_1 X_0 

We can see that all of the bits of result is the same as v7 except the MSB which is now 1. Therefore, v7 | 0x8000000000000000LL sets the MSB of v7

Similarly for v7 & 0x7FFFFFFFFFFFFFFFLL

The mask is 0x7FFFFFFFFFFFFFFFLL, which has all bits set to 1 except for the most significant bit (MSB), which is 0.

index - 63   62   61   ... 2   1   0
bits  - 0    1    1    ... 1   1   1

We want to perform the bitwise AND operation between v7 and the mask.

index - 63   62   61   ... 2   1   0
bitsX - X_63 X_62 X_61 ... X_2 X_1 X_0

When we perform the bitwise AND operation:

For each bit position, we apply the rule X & 1 = X and X & 0 = 0

index - 63   62   61   ... 2   1   0
bitsX - X_63 X_62 X_61 ... X_2 X_1 X_0
mask  - 0    1    1    ... 1   1   1
result- 0    X_62 X_61 ... X_2 X_1 X_0

The result retains all bits of v7 except the MSB, which is now 0. Therefore, v7 & 0x7FFFFFFFFFFFFFFFLL clears the MSB of v7