Unsigned into are just positive values and at Binary level, they would be represented as such: (if we were working with 4 bits)
Signed values aim to have negatives, but require a system to save them.
The first proposition to save them is to use the first bit as a signed bit:
This system is not perfect as it yields you a position of -0 and if you add positive with negative numbers in this binary sequence, the math won’t make sense (note: we ignore anything that goes beyond our range of 4 bits):
The next system proposed combine the idea of using a signed bit while the rest of the sequence is the inverse of positive or negative:
This is called Ones Complement. If you were to apply addition between the negative and positive numbers, you would yield a closer result but not quite there yet. This is because we still have a -0 position:
If you see your results and the pattern above, you will notice that the actual answer is always +1 position away from what you are getting. This brings us to the system used to stored signed integers: Twos Complement. Here we will use a sign digit, invert the sequence, and finally add 1.
Our math finally checks out! It is odd that you end up with a -8 but no 8, however this brings us to a great way you can think of the positions:
The following operators will execute some kind of operation at the binary level. Note that the binary representation will depend on whether the interger is signed or unsigned.
Bitwise NOT written as ~ will invert the binary sequence of the value. In an signed value, this will flip the signed digit as well!
Bitwise AND written as & will compare two bits and returns 1 if they are both 1. It will return 0 if they are not the same.
Bitwise OR written as | will compare two bits and return 1 if either one is 1. It will return 0 only if both are 0.
Bitwise XOR written as ^ will compare two bits and return 1 if exactly one is 1. It will return 0 in any other configuration.
The last two operations will shift the sequence to the left or right depending on the operator used and the amount specified.
Written as: valueToChange << NumberOfShifts. This will shift the sequence by that many positions towards the left and fill in the vacant spots on the right with zeroes. Note that with Signed ints the number doubles.
Written as: valueToChange >> NumberOfShifts. This will shift the sequence by that many positions towards the right and handles the vacant spots on the left depending on the valueToChange. If it is an Unsigned Int, these spots are filled with 0. If it is a Signed Int, then the spots are filled according to the sign digit. Shifting to the right will divide the value in half though it will not change a negative number into a positive number