3
$\begingroup$

So I am having a bit of an issue. First, what is the difference between doing an unsigned binary integer subtraction and doing a signed integer subtraction? I think that is what is confusing me. For an unsigned integer, I was told that you have to add a 0 next to the most significant bit (I may be wrong), but I don't feel comfortable with that. After watching a couple of videos on youtube, I tried to the subtraction.

0011 0001 – 1010 1011

My thought process: I decided to take 1010 1011 and do one's complement and then two's complement and then add it to 0011 0001.

Click here to see my work

$\endgroup$

2 Answers 2

2
$\begingroup$

In unsigned binary, all numbers are positive and you can't subtract a larger one from a smaller one. If we translate your problem to base $10$ we get $49-171$ which does not have an answer. For unsigned binary you just do subtraction like you learned in school except in base $2$, borrowing when necessary. So if we want to do your problem in reverse, $171-49$ we get $$\begin {align}1010 1011&\\ \underline {-0011 0001}& \\01111010& \end {align}$$ where we borrowed in the $2^5$ place and it carried to the next two.

$\endgroup$
4
  • $\begingroup$ Oh okay that makes sense. How about if they are signed though? I want to know the differences. $\endgroup$ Commented May 25, 2016 at 2:41
  • $\begingroup$ For signed binary, you need to resolve the signs. If you have $a-b$ and $b$ is negative (check the sign bit), you flip the sign bit and add. If you have $a+b$ and $a$ is negative, you do $b-a$ and so on. This is why computers use two's complement-you don't have to worry about it. $\endgroup$ Commented May 25, 2016 at 3:37
  • $\begingroup$ Oh okay I see. My other concern is with the unsigned subtraction with this one. I took the 0011 0001, flipped the bits, and added 1, and you get 1100 1111. Then, I did 1010 1011 + 1100 1111 = 1 0111 1010, which is what you have except I think you ignored the bit. Wouldn't this be overflow since carry in (0) does not equal carryout (1)? $\endgroup$ Commented May 25, 2016 at 3:57
  • $\begingroup$ You are confusing twos complement and signed binary. Signed binary just has a sign bit but leaves the rest of the number the same, so $-1=1000 0001$ Twos complement inverts all the bits and adds one. It has the advantage that you can do the same arithmetic for positive and negative numbers, which is not true for signed binary or ones complement. Please be clear which you are talking about. $\endgroup$ Commented May 25, 2016 at 4:48
0
$\begingroup$

This is a reasonable answer from a mathematical point of view, but not a great answer from computer science point of view. To understand this you want to look at the most common two's complement binary math https://notesformsc.org/2s-complement-subtraction/. This also overlaps an interesting subject in math, modular arithmetic (since register sizes are fixed) used to prevent rollover issues when doing timing math see http://www.gammon.com.au/forum/?id=12127.

The C++ program below shows that if you interpret the number as time subtracting T2-T1 works even if the counter has rolled over (gone from large to small) once. It also shows that if you allow promotion to large types you get, what may be initially, unexpected values.

#include <iostream> #include <cmath> #include <bitset> void take_short_diff(unsigned short T1, unsigned short T2) { //Force all math to happen without promotion unsigned char diff = (unsigned char)(T2 - T1); //Ints below are just so it doesn't print as characters, they don't impact the problem std::cout << "\n\nT1 =" << (int)T1 << "\nT2 =" << (int)T2 << "\ndiff=" << (int)diff; //Show the binary pattern std::cout << "\nT1 =" << std::bitset<8>(T1) << "\nT2 =" << std::bitset<8>(T2) << "\ndiff=" << std::bitset<8>(diff); //Allow promotion to short short diff_short = T2 - T1; std::cout << "\ndiff short=" << diff_short; std::cout << "\n" << std::bitset<16>(diff_short); //Allow promotion to unsigned short unsigned short diff_short_u = T2 - T1; std::cout << "\ndiff short unsigned=" << diff_short_u; std::cout << "\n" << std::bitset<16>(diff_short_u); } void main() { take_short_diff(0, 2); take_short_diff(253, 255); take_short_diff(254, 1); } 
$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.