I'm taking a computer organization and assembly language course. The written part of our lab this week has a question on it that has me stumped. The question reads...
Subtract the following unsigned binary numbers (show the borrow and overflow bits). Do not convert to two's complement.
0101 0111 1101
-1110 1011 0110
--------------
I realize that the answer is -1001 0011 1001 but I'm having a hard time trying to figure out how to borrow to actually perform this subtraction by taking the larger number and subtracting it from the smaller number and show my work. My whole life when subtracting a large number from a small number I have reversed the problem and instead subtracted the smaller number from the larger number and added a negative sign in front of the result. I asked the professor and he says that he wants the problem solved the way that it is written. I am not allowed to solve this by subtracting the smaller number from the larger number and negating like I normally would. I haven't been able to find any examples online of subtracting a larger unsigned binary number from a smaller one.
I would really appreciate it if someone could describe to me how to perform subtraction in this scenario.
Update:
#Alex is correct. The professor was looking for
0110 1100 0111 (1735)
Thanks everyone.
You do it the same way irrespective of which number is bigger and which is smaller.
bb b bb <- borrows
0101 0111 1101 (1405)
-1110 1011 0110 (3766)
--------------
0110 1100 0111 (1735?)
Now, if you want a proper difference, you need to take into account the overflow since the above result doesn't include the sign bit:
b bb b bb <- borrows
0 0101 0111 1101 (1405)
-0 1110 1011 0110 (3766)
----------------
1 0110 1100 0111 (-2361 signed 2's complement)
Really, the CPU doesn't care what gets subtracted from what. It uses the same algorithm for integer addition/subtraction, moreover, this algorithm is the same for signed and unsigned integers. You only have to correctly interpret the result and the carry and overflow flags. That's all.
simply subtract the two binary numbers as they are, then take the 2's complement of the result. voila!
Related
Last week I learned about arithmetic with binary numbers especially substraction with two's complement, it was pretty easy so far but something bothers me a little bit. Why is 0 - 1 = 1 with a borrow of 1?
Sure its -1 but should we get some result like 1001 (4 bits for size)? Can someone please explain?
0-1 is not 1 in binary
0-1 does not equal 1 in two's complement with signed numbers. But its representation does have alot of ones in it: you should get 1111.
Negative numbers in two's complement:
In two complement's format (which computers use) with signed magnitude, one bit is reserved to represent the sign of the number. By convention this is the leftmost bit, where 0 indicates a positive value and 1 indicates a negative value.
To get the representation of a negative number we follow two steps:
Flip all the bits
Then increment by one
Additive Inverse of 7:
7=0111
1000 // Flip the bits
-7=1001 // Add +1
So why do we get 1111 when we subtract 0-1?
How do we substract in two's complement? We subtract A-B by taking the additive inverse (the opposite) of B and adding the numbers.
So with A=0 and B=1:
Take the additive inverse by inverting and then increment by 1.
Additive Inverse of B:
B= 0001
-B= 1110 // Invert
-B= 1111 // Increment +1
Now sum A + (-B) :
A=0000
(+) -B=1111
-----------
A+(-B)=1111
Note that if we are only allowed one bit. We can't represent negative numbers since there's no room for the value.
If I have a negative decimal number, say -5 for example, and converted it to hexadecimal format. Would I be able to simply put a negative sign in front of the hexadecimal number? Or is there another way of doing it like with 2's compliment in binary?
There is no "one way" to represent a negative number. That said there are a number of standard ways to represent a negative number. To keep the math simple, I'm going to assume that all number use 4 bits.
Use a sign bit (in binary) 0111 is 7, but 1111 is -7. (also can be done in reverse 0111 is -7 1111 is 7.
Use the 1's complement. 0111 is 7, but 1000 is -7 (all bits flipped. This has the odd property of 0000 being a natural 0, but 1111 being a (negative zero) -0.
Use the 2's complement. Negation is 1's complement plus one, so 0111 is 7, but 1000 + 0001 or 1001 is -7. This leverages integer overflow to maintain no negative zero. 0000 negated is 1111 + 0001 which overflows to 0000. It also has a few nice properties such that adding some number plus its negative resolves to zero, provided that both numbers can be written (there is one more negative number than a positive one). 7 + (-7) is 0111 + 1001 which overflows to 0 0000.
You may hear the saying that the "bits mean whatever you want them to mean". This means that you can come up with any number of ways to represent anything, you just build a "map" of the bits to the values you desire. For example, here is an odd, whimsical way of representing prime numbers.
(bits) => value
0001 => 2
0010 => 3
0011 => 5
0100 => 7
0101 => 11
0110 => 13
0111 => 17
(and so on)
Such a system would be hard to do math with, but it is an example that you don't have to be constrained to a specific way of doing anything. As long as you build routines to produce the expected output from the expected input, you can make the mapping of bits to values mean what ever you want it to mean.
This idea of meaning being a thing you impose upon the bits is important. When you start to deal with text, the "encoding" is the meaning imposed upon the bits storing text, with the same bits sometimes encoding different letters in different encoding schemes.
I am reading a book about Cryptography, and I am stuck in a question. I am really trying to solve it for weeks. But I think the problem is I couldn't understand the whole picture. The question was like this :
We conduct a known-plaintext attack on an LFSR-based stream cipher. We know that the plaintext sent was:
1001 0010 0110 1101 1001 0010 0110
By tapping the channel we observe the following stream:
1011 1100 0011 0001 0010 1011 0001
1- What is the degree m of the key stream generator?
2- What is the initialization vector?
3- Determine the feedback coefficients of the LFSR.
4- Draw a circuit diagram and verify the output sequence of the LFSR.
Many thanks for your help to me to understand cryptography and LFSR.
You are referring to Understanding Cryptography by Paar and Pelzi, right? The second chapter can be found online on the Springer site which should be legal given Springer is the publisher.
I'd say the second list is the ciphertext, i.e. the plaintext XORed with the keystream. The keystream would then be
1001 0010 0110 1101 1001 0010 0110
XOR 1011 1100 0011 0001 0010 1011 0001
= 0010 1110 0101 1100 1011 1001 0111
or
0010111 0010111 0010111 0010111
grouped in blocks of 7 bits. Given theorem 2.3.1 "The maximum sequence length generated by an LSFR of degree m is (2^m)-1" you can guess that the degree might be 3, as the sequence length of the LSFR appears to be 7. Note that the degree counts the internal states of the LSFR and does not refer to the degree of the polynomial. According to formula (2.1) its degree is one less.
So what you want to calculate is a solution to the equations
p(0,0,1)=0
p(0,1,0)=1
p(1,0,1)=1
for p(s_0,s_1,s2)=p_0*s_0+p_1*s_1+p_2+s_2 and check that rest of the key stream matches this formula, too. Doing this you end up with the following matrix:
0 0 1 | 0
0 1 0 | 1
1 0 1 | 1
So p_0=1, p_1=1 and p_2=0. Which does match the rest of the keystream.
The question provides insufficient information. There are multiple solutions.
Step one is to determine the key stream. Since you know the plaintext and the ciphertext, that should be easy. Just xor the two.
The standard way for an LFSR is to use a primitive polynomial of degree m over the field with just two elements, 0 and 1. In such a case the length of the sequence before repeating itself is 2^m -1. Here you have 28 bits. So the intended solution is to have m = 3. Indeed you can break the 28 bits of the key stream breaks into 3 repeated instances of the first 7 bits.
Under the assumption that m = 3, the first 3 bits of the key stream is the initialization vector. From this you should be able to determine the taps in the LFSR. You can check your answer with the fact that there are only two primitive polynomials of degree 3 over the field with two elements, x^3 + x^2 + 1 and x^3 + x + 1.
The reason there is insufficient information is because the key stream could be the first 28 bits of an LFSR of degree 5 or degree 6 or degree 7, .... You get the idea.
ADDED
Suppose you have LFSR of degree m with initialization vector 0000...01. I'm doing left-shifting. Now do one step of the LFSR. The left-most bit is discarded, the remaining m-1 bits are shifted left and the new right-most bit is the xor of all the taps. Hence given the initialization vector the new right-most bit is one if and only if there is a tap on the right-most cell. Now do another shift. The new right-most bit is a combination of xors of the two right-most cells. From the previous step you know if there is a tap on the last cell. Hence after two shifts you know if there are any taps on two right-most cells. Continuing this way you can determine all the taps.
I want to substract 92H-64H in two's complementary and state whether carry flag bit C and overflow flag bit V are 1 or 0.
So far no problem to convert and check in decimal that it is
146-100=46=2EH
But I get lost in performing substraction to check bits bit by bit. I can imagine it's done in binary, but how? Appreciate any help!!
You have to operate in binary. Hexadecimal is no more than an easy (=less digits) way to show numbers that are binary internally.
That said, your two numbers:
92h - 64h . I assume you work with 8 bits. Translating them to binary: 1001 0010 - 0110 0100
To substract using c2, take the second number, 0110 0100
Invert its bits: 1001 1011
Add one: 1001 1011 + 1 = 1001 1100
Add this new number to the previous first number:
1001 0010
1001 1100
---------
10010 1110
The carry is the 9-th bit of this addition. In this case is 1.
The overflow bit is calculated as follows: take the 8-th bit of each number in the addition: they are 1, 1, and 0. These are the sign bits of each number.
There is overflow if both signs of operands 1 and 2 are the same, bit the sign of the result is different. In any other case, there's no overflow.
In this addition, signs of both operands are the same (1) but sign of the result is not (it's 0), so there is overflow here.
By the way, the result of this addition (taking its lower 8 bits, discarding the carry bit) is the result of the original substraction.
The result of the addition is 0010 1110, which is 2E in hexadecimal.
So 92h - 64h = 2Eh, Carry is 1, Overflow is 1.
I don't understand how I can add in IEEE 754 Floating Point (mainly the "re-alignment" of the exponent)
Also for rounding, how does the Guard, Round & Sticky come into play? How to do rounding in general (base 2 floats that is)
eg. Suppose the qn: Add IEEE 754 Float represented in hex 0x383FFBAD
and 0x3FD0ECCD, then give answers in Round to 0, \$\pm \infty\$,
nearest
So I have
0x383FFBAD 0 | 0111 0000 | 0111 1111 1111 0111 0101 1010
0x3FD0ECCD 0 | 0111 1111 | 1010 0001 1101 1001 1001 1010
Then how should I continue? Feel free to use other examples if you wish
If I understood your "re-alignment" of the exponent correctly...
Here's an explanation of how the format relates to the actual value.
1.b(22)b(21)...b(0) * 2e-127 can be interpreted as a binary integer shifted left by e-127 bit positions. Of course, the shift amount can be negative, which is how we get fractions (values between 0 and 1).
In order to add 2 floating-point numbers of the same sign you need to first have their exponent part equal, or, in other words, denormalize one of the addends (the one with the smaller exponent).
The reason is very simple. When you add, for example, 1 thousand and 1 you want to add tens with tens, hundreds with hundreds, etc. So, you have 1.000*103 + 1.000*100 = 1.000*103 + 0.001*103(<--denormalized) = 1.001*103. This can, of course, result in truncation/rounding, if the format cannot represent the result exactly (e.g. if it could only have 2 significant digits, you'd end up with the same 1.0*103 for the sum).
So, just like in the above example with 1000 and 1, you may need to shift to the right one of the addends before adding their mantissas. You need to remember that there's an implict 1. bit in the format, which isn't stored in the float, which you have to account for when shifting and adding. After adding the mantissas, you most likely will run into a mantissa overflow and will have to denormalize again to get rid of the overflow.
That's the basics. There're special cases to consider as well.