ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I’m wondering about the fine logical points in the evaluation of the following example of binary manipulation.
The following monograph on “Representing signed integer numbers inside a computer”
http://www.mathcs.emory.edu/~cheung/Courses/561/Syllabus/1-Intro/2-data-repr/signed.html
gives the following example for “subtracting 2’s complement numbers”. [Sorry that I can't figure out how to post this in a properly formatted way as an arithmetic operation]
Example: subtract -9 from +5 in binary format:
00000101 - 11110111 = 00001110
It seems that, in order to proceed with the above calculation, one must first evaluate the one’s complement of the ‘negative’ binary number so that it is now a ‘positive’ representation of a binary.
(I'm aware that the unary one's complement operator has precedence over the addition/subtraction operator).
What confuses me is that to get the correct binary result, I must still treat that number as a negative after employing the complement operator, so that the operation of subtracting a ‘negative’ becomes, in effect, an addition of the two numbers.
Is there a simpler way of viewing what’s going on here that will help un-rattle my brain?
It seems that, in order to proceed with the above calculation, one must first evaluate the one’s complement of the ‘negative’ binary number so that it is now a ‘positive’ representation of a binary.
I don't know where you got that idea, but it's incorrect.
Quote:
(I'm aware that the unary one's complement operator has precedence over the addition/subtraction operator).
If you are talking about the C unary complement operator precedence, it's completely irrelevant.
Quote:
What confuses me is that to get the correct binary result, I must still treat that number as a negative after employing the complement operator, so that the operation of subtracting a ‘negative’ becomes, in effect, an addition of the two numbers.
Subtracting any number (negative or positive) is equivalent to adding its negation, regardless of what base you're using. So yes, subtracting a negative is equivalent to adding the positive. Again, nothing to do with binary in particular.
Before I go further with your example, did you mean to write:
Quote:
signed interpretation: 10=-2, 11=-1, 00=0, 11=1?
--or am I missing something fundamental about the difference between signed & unsigned?
[2 PM: Oops! I see that I'm not really understanding your reference to "signed interpretation" at all!]
I would add that other examples in the cited link were obvious: only the example I listed caused my dilemma.
Last edited by atlantis43; 03-21-2015 at 01:14 PM.
No, I 'bolded' what I meant, as I thought that the 'significant' digit being '1' in '11' would indicate 'negative' in a 'signed' number. I think that's what's confusing me in the term "signed interpretation", where 11 is listed as equal to both -1 and +1.
At my level of understanding, I only know such things as that an unsigned byte can represent (digital) 0-255, and a signed byte can represent (digital) -128 to + 127.
Subtracting any number (negative or positive) is equivalent to adding its negation, regardless of what base you're using. So yes, subtracting a negative is equivalent to adding the positive. Again, nothing to do with binary in particular.
Just to understand what goes on in the processor with complements, etc, I'm wondering how the processor would, for a = 27 and b = -34, calculate (a) - (b). Would it not first have to convert b into it's 2's complement, or would the processor be able to evaluate that the double negative represents mere addition. If not the latter, then I presume that it would process the 2's complement twice in the above calculation, for subsequent addition?
I'm wondering how the processor would, for a = 27 and b = -34, calculate (a) - (b). Would it not first have to convert b into it's 2's complement,
No, the binary algorithms for addition and subtraction work independent of the signed/unsigned interpretation.
That said, it's possible the processor might implement subtraction internally by performing negation followed by addition (maybe because it saves silicon). But then it would always perform the negation, even if b is "positive".
Quote:
If not the latter, then I presume that it would process the 2's complement twice in the above calculation, for subsequent addition?
Not sure what "subsequent addition" you refer to here.
ie, first to get the complement of the subtrahend, and 'subsequently' add it to the minuend to get the result.
Oh, I thought "subsequent addition" implied more than 1 addition. But now I'm not sure what you meant by "process the 2's complement twice". Supposing subtraction is implemented like
Code:
+------------------------------+
| subtract |
| +----------+ |
a ---|---------------| | |
| +--------+ | add |---|---- (a - b)
b ---|--| negate |---| | |
| +--------+ +----------+ |
| |
+------------------------------+
Sometimes the CPU doesn't have "signed-add/sub" and "unsigned-add/sub" operations, it simply performs binary addition/subtraction, then sets two flags, one for 'unsigned overflow' and one for 'signed overflow' (these are not the same, see the (!) marks in post #3).
Example: subtract -9 from +5 in binary format:
00000101 - 11110111 = 00001110
It seems that, in order to proceed with the above calculation, one must first evaluate the ones complement of the negative binary number so that it is now a positive representation of a binary
Wrong at that very point.
11110111 is TWO's complement representing -9
Why?
00001001 is +9
One's complement of that becomes: 11110110
To make it Two's complement you add binary one to the One's complement, so it becomes: 11110111
Now to convert that negative number back to positive, thus making it so you would be adding a positive versus subtracting a negative, you take the reverse of that Two's complement.
To do that you first take the One's complement, which is inversion of all ones and zeros: 00001000
And then you add binary one: 00001001
That result is +9
So now the mathematical equation becomes adding +9 to +5, which becomes +14 --> 00001110
Some things to note:
When converting sign you ALWAYS invert bits first and then add binary one no matter which direction you are going
It is important to understand the size of variables as they are represented in your machine, thus if you call something an integer, "int" you need to understand if that is 8, 16, 32, or 64 bits or something different. You can test this by using something like printf("Size of an integer is: d\n, sizeof(int));
When performing these transformations, be aware of how large the variable is in bits, but also declare your variables as unsigned, be that unsigned char, unsigned short, unsigned int, unsigned long, and so forth. Why? Because "you" are performing the transformations on your own. If you declare a variable as signed, the compiler will treat it as such and there could be complications, best to declare it as unsigned
There are two ways to invert bits, "Exclusive OR" or the Invert Operator:
Exclusive OR is the ^ operator and to invert a variable you would exclusive OR that variable against a same sized variable populated as all 1's. For instance, to invert a byte, 8-bits using XOR you would do something like this: byte-value-result = original-byte-value ^ 0xFF
Invert Operator is the ~ operator and to invert a variable you would apply the invert operator to it like this: byte-value-result = ~original-byte-value
Note that just inverting using either XOR or Invert is only the first part, you next need to add "1" to complete the sign conversion
As others have pointed out, you can do this logically on paper to back up your programming.
I can't emphasize enough to be cautious and use unsigned variables if you're performing the sign conversions with your own programming. Because the language and compiler can deal with signed numbers quite correctly, however in analyzing them you wish to avoid any automatic conversions which would confuse you in your study.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.