Logical left shift of 0 - logical-operators

Here my question is why the logical left shift 0 is one.
1<<0 = 1, but how?
According to definition the logical left shift works by shifting the bits towards left by n bits.
Logical left shifts works by multiplying number with 2
n << number = 2*n*number; not in case of number=0;
Even if the 0 or the negative numbers are stored in two's complement, so for zero all the bits must be one, then how its logical left shift works.
1<<0 =1 1<<2=4
2<<0 =2 2<<2=8
3<<0 =3 3<<2=12

Bit shift left multiplies the right hand number by 2 to the power of the left hand side. For example: 1 << 2 is the same as 1 * 2^2 (where ^ represents exponent, not XOR).
1 in binary is 0001, then bitshifting it by 0 won't do anything, which aligns with what you observed.
So any number x << 0 is equivalent to x * 2^0, which is x * 1, which is just x.

you are doing a mistake by considering it "2 * n" but its "2^n". like 2*3=6 but 2^3 will be 8. secondly, if you have 0001 and you are shifting 0-bit than it wouldn't affect because 2^0=1 and 1*1 will be 1. but if you shift 1-bit it will multiply it with "2". for example, 0001 and you shifted 1-bit. it becomes 0010 which is 2.

Related

How does the formula x & (x - 1) works?

From Hacker's Delight: 2nd Edition:
The formula here seems a little bit awkward here. How is some x vector is subtracted from 1 vector (presumbly 0x1111 1111) when x is smaller than 1? (Like: (as given in example) 0x0101 1000 - 0x0000 0000 doesn't make any sense to me) The former is a smaller number than the first one and the words aren't storing signed vectors either. Is that something related to RISC specific here or what?
As specified in the notation section of the book. A bold letter corresponds a vector for word like x = 00000000. And a bold one differs from a light face 1. As bold 1 = 11111111 which is an 8 bit word.
Edit2: Special Thanks to Paul Hankin to figure out the unconventional notations used here. A bold faced one refers to 32 bit size word which is [00000001] and a light faced 1 refers to a number one as in C.
Subtracting 1
Since we're more familiar with decimal than with binary, it sometimes helps to look at what happens in decimal.
What happens when subtracting 1 in decimal? Take for example 1786000 - 1 = 1785999.
If you subtract 1 from a positive number x in decimal:
all the zeroes at the right of x become 9;
the rightmost nonzero digit of x becomes 1 less;
other digits are unaffected.
Now, in binary, it works exactly the same, except we only have 0 1 instead of 0 123456789.
If you subtract 1 from a number x in binary:
all the zeroes at the right of x become 1;
the rightmost nonzero bit of x becomes 0;
other bits are unaffected.
What about negative numbers? Happily, representation using 2's complement is such that negative numbers behave exactly like positive numbers. In fact, when looking at the bits of x, you can subtract 1 from x without needing to know whether x is a signed int or an unsigned int.
x & (x-1)
Let's start with an example: x = 01011000. We can subtract 1 the way I just explained:
x = 01011000
x-1 = 01010111
Now what's the result of the bitwise-and operation x & (x-1)? We take the two bits in each column; if they are both 1, we write 1; if at least one of them is 0, we write 0.
x = 01011000
x-1 = 01010111
x&(x-1) = 01010000
What happened?
all the zeroes at the right of x remain zero;
the rightmost 1 of x becomes a 0 because of x-1;
all other bits are unaffected, because they are the same in x and x-1.
Conclusion: we have zeroed the rightmost 1 of x, and left all other bits unaffected.
Let's take a look at an what x-1 does.
Assume x is a value '???? 1000 (? are 0 or 1)
=> x-1 = ???? 0111
=> x & (x-1) = ???? 0000
It's very similar no matter where the right most 1 is placed within x.
Requested example:
x=00001111
=> x-1=00001110
=> x & (x-1) = 00001110
P.s. x-1 = 00001110 - 00000001 (<=> 00001110 + 11111111)

integer divison with negative remainder

I'm trying to find a name for mathematical division operation which can produce negative reminder.
Examples of expected:
5 %? 2 = 2*2 + 1
11 %? 3 = 4*3 - 1
module of reminder should be as small as possible.
Does someone knew the name of such operation?
Computer language remainder functions return a positive remainder. What you need is simple. In your second example you want is a remainder of -1.
11 %? 3 = 4*3 - 1
But what you get is a remainder of 2.
11 %? 3 = 3*3 + 2
As I said in the comments, check the remainder 2 against half the divisor 3/2 = 1.5. Since the remainder is greater than half the divisor, subtract the divisor:
2 - 3 = -1
Yes, you will have to store a real number for half the divisor.

Convert floating point number from binary to a decimal number

I have to convert floating point number from binary to usable decimal number.
Of course my floating point number has been separated into bytes, so 4 bytes total.
1 2 3 4
[xxxxxxxx][xxxxxxxx][xxxxxxxx][xxxxxxxx]
These 4 bytes are already converted to decimal, so I have e.g.
1 2 3 4
[0][10][104][79]
Now Mantissa is held in three parts, two rightmost bytes (3 & 4) and in byte 2 but without the MSB bit (that one is easy to mask out, so let's assume we have a nice decimal number there as well). So three decimal numbers.
Is there an straightforward mathematical conversion to a floating point mantissa for these three decimal numbers?
This is along the lines: if I needed to get an integer, the formula would be
10 * 65536 + 104 * 256 + 79.
Call these bytes a, b, and c. I assume a has already been masked, so it contains only the bits of the significand and none of the exponent, and that the number is IEEE-754 32-bit binary floating-point, with bytes taken with the appropriate endianness.
If the raw exponent field is 1 to 254 (thus, not 0 or 255), then the significand is:
1 + a*0x1p-7 + b*0x1p-15 + c*0x1p-23
or, equivalently:
(65536*a + 256*b + c) * 0x1p-23 + 1.
If the raw exponent field is 0, then remove the 1 from the sum (the number is subnormal or zero). If the raw exponent field is 255, then the floating-point value is infinity (if a, b, and c are all 0) or a NaN (otherwise).
I cannot be of much help, since it has been a while since I did conversions, but I hope you find this tutorial useful.

Why we need to add 1 while doing 2's complement

The 2's complement of a number which is represented by N bits is 2^N-number.
For example: if number is 7 (0111) and i'm representing it using 4 bits then, 2's complement of it would be (2^N-number) i.e. (2^4 -7)=9(1001)
7==> 0111
1's compliment of 7==> 1000
1000
+ 1
-------------
1001 =====> (9)
While calculating 2's complement of a number, we do following steps:
1. do one's complement of the number
2. Add one to the result of step 1.
I understand that we need to do one's complement of the number because we are doing a negation operation. But why do we add the 1?
This might be a silly question but I'm having a hard time understanding the logic. To explain with above example (for number 7), we do one's complement and get -7 and then add +1, so -7+1=-6, but still we are getting the correct answer i.e. +9
Your error is in "we do one's compliment and get -7". To see why this is wrong, take the one's complement of 7 and add 7 to it. If it's -7, you should get zero because -7 + 7 = 0. You won't.
The one's complement of 7 was 1000. Add 7 to that, and you get 1111. Definitely not zero. You need to add one more to it to get zero!
The negative of a number is the number you need to add to it to get zero.
If you add 1 to ...11111, you get zero. Thus -1 is represented as all 1 bits.
If you add a number, say x, to its 1's complement ~x, you get all 1 bits.
Thus:
~x + x = -1
Add 1 to both sides:
~x + x + 1 = 0
Subtract x from both sides:
~x + 1 = -x
The +1 is added so that the carry over in the technique is taken care of.
Take the 7 and -7 example.
If you represent 7 as 00000111
In order to find -7:
Invert all bits and add one
11111000 -> 11111001
Now you can add following standard math rules:
00000111
+ 11111001
-----------
00000000
For the computer this operation is relatively easy, as it involves basically comparing bit by bit and carrying one.
If instead you represented -7 as 10000111, this won't make sense:
00000111
+ 10000111
-----------
10001110 (-14)
To add them, you will involve more complex rules like analyzing the first bit, and transforming the values.
A more detailed explanation can be found here.
Short answer: If you don't add 1 then you have two different representations of the number 0.
Longer answer: In one's complement
the values from 0000 to 0111 represent the numbers from 0 to 7
the values from 1111 to 1000 represent the numbers from 0 to -7
since their inverses are 0000 and 0111.
There is the problem, now you have 2 different ways of writing the same number, both 0000 and 1111 represent 0.
If you add 1 to these inverses they become 0001 and 1000 and represent the numbers from -1 to -8 therefore you avoid duplicates.
I'm going to directly answer what the title is asking (sorry the details aren't as general to everyone as understanding where flipping bits + adding one comes from).
First let motivate two's complement by recalling the fact that we can carry out standard (elementary school) arithmetic with them (i.e. adding the digits and doing the carrying over etc). Easy of computation is what motivates this representation (I assume it means we only 1 piece of hardware to do addition rather than 2 if we implemented subtraction differently than addition, and we do and subtract differently in elementary school addition btw).
Now recall the meaning of each of the digit's in two's complements and some binary numbers in this form as an example (slides borrowed from MIT's 6.004 course):
Now notice that arithmetic works as normal here and the sign is included inside the binary number in two's complement itself. In particular notice that:
1111....1111 + 0000....1 = 000....000
i.e.
-1 + 1 = 0
Using this fact let's try to derive what the two complement representation for -A should be. So the problem to solve is:
Q: Given the two's complement representation for A what is the two's complement's representation for -A?
To do this let's do some algebra using values we know:
A + (-A) = 0 = 1 + (-1) = 11...1 + 00000...1 = 000...0
now let's make -A the subject expressed in terms of numbers expressed in two's complement:
-A = 1 + (-1 - A) = 000.....1 + (111....1 - A)
where A is in two's complements. So what we need to compute is the subtraction of -1 and A in two's complement format. For that we notice how numbers are represented as a linear combination of it's bases (i.e. 2^i):
1*-2^N-1 + 1 * 2^N-1 + ... 1 = -1
a_N * -2^N-1 + a_N-1 * 2^N-1 + ... + a_0 = A
--------------------------------------------- (subtract them)
a_N-1 * -2^N-1 + a_N-1 -1 * 2^N-1 + ... + a_0 -1 = A
which essentially means we subtract each digit for it's corresponding value. This ends up simply flipping bits which results in the following:
-A = 1 + (-1 - A) = 1 + ~ A
where ~ is bit flip. This is why you need to bit flip and add 1.
Remark:
I think a comment that was helpful to me is that complement is similar to inverse but instead of giving 0 it gives 2^N (by definition) e.g. with 3 bits for the number A we want A+~A=2^N so 010 + 110 = 1000 = 8 which is 2^3. At least that clarifies what the word "complement" is suppose to mean here as it't not just the inverting of the meaning of 0 and 1.
If you've forgotten what two's complement is perhaps this will be helpful: What is “2's Complement”?
Cornell's answer that I hope to read at some point: https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html#whyworks

Adding negative and positive binary?

X = 01001001 and Y = 10101010
If I want to add them together how do I do that? They are "Two's Complement"...
I have tried a lots of things but I am not quite sure I am getting the right answer since there seems to be different type of rules.
Just want to make sure it is correct:
1. Add them as they are do not convert the negative
2. Convert the negative number you get and that's the sum.
f.eks
01001001+10101010 = 11110011 => 00001100 => 1101 => -13
Or?
1. Convert the negative
2. Add them together and convert the negative
f.eks
01001001+10101010 => 01001001 + 01010110 => 10011111 => 01100001 => -97
So basically what I want to do is to take: X-Y, and X+Y
Can someone tell me how to do that?
Some resource sites:
student-binary
celtickane
swarthmore
The beauty of two's complement is that at the binary level it's a matter of interpretation rather than algorithm - the hardware for adding two signed numbers is the same as for unsigned numbers (ignoring flag bits).
Your first example - "just add them" - is exactly the right answer. Your example numbers
01001001 = 73
10101010 = -86
So, the correct answer is indeed -13.
Subtracting is just the same, in that no special processing is required for two's complement numbers: you "just subtract them".
Note that where things get interesting is the handling of overflow/underflow bits. You can't represent the result of 73 - (-86) as an 8-bit two's complement number...
Adding in two's complement doesn't require any special processing when the signs of the two arguments are opposite. You just add them as you normally would in binary, and the sign of the result is the sign you keep.
And just to make sure you understand two's complement, to convert from a positive to a negative number (or vice versa): invert each bit, then add 1 to the result.
For example, your positive number X = 01001001 becomes 10110101+1=10110110 as a negative number; your negative number Y = 10101010 becomes 01010101+1=01010110 as a positive number.
To subtract Y from X, negate Y and add. I.E. 01001001 + 01010110.
Your confusion might be because of the widths of the numbers involved. To get a better feel for this you could try creating a signed integer out of your unsigned integer.
If the MSB of your unsigned integer is already 0, then you can read it as signed and get the same result.
If the MSB is 1 then you can append a 0 to the left to get a signed number. You should sign-extend (that is, add 0s if the MSB is 0, add 1s if the MSB is 1) all the signed numbers to get a number of the same width so you can do the arithmetic "normally".
For instance, using your numbers:
X = 01001001: Unsigned, MSB is 0, do nothing.
Y = 10101010: Signed, did nothing with X, still do nothing.
But if we change the MSB of X to 1:
X = 11001001: Unsigned, MSB is 1, Add a 0 --> 011001001
Y = 10101010: Signed, extended X, so sign-extend Y --> 110101010
Now you have two signed numbers that you can add or subtract the way you already know.
01001001 + 10101010 = 11110011 => 00001100 => 1101 => -13
The first addend is 73. The second addend is -86. 86 = 101010. Padding to 8 bits including the 1 for the negative sign, -86 = 10101010
Both addends are in Sign-bit representation.
Solving them their sum is 1 1 1 1 0 0 1 1 which is an encoded binary (equivalent to having undergone One's Complement by inversion then Two's Complement by adding 1).
So do the reverse to have the decimal number. This time do first subtract 1 as inverse of Two's Complement = 1 1 1 1 0 0 1 1 - 1
= 1 1 1 1 0 0 1 0 then invert as in One's Complement = 0 0 0 0 1 1 0 1 which is equal to 13. Having done such reversal or having acknowledged One's complement and Two's Complement, the answer is negative. So affix the negative sign = -13

Resources