Jump to content

Storage of Two's Compliment Negative Numbers

I have a question I've been pondering for the longest time about two's complement negative numbers. I understand the theory behind two's compliment, you take a number, invert it and add 1 to get the negative equivalent of it for mathematical operations. This much makes sense to me and I can see the benefits of using it over signed values or one's complement. The problem I run into is what happens to the number when the computer wants to put it in memory. Suppose a subtraction operation is performed by the computer like 5 - 6, the result being negative 1. This would look like 11111111 in 8 bit binary, my question is what does the computer do when it stores this number in memory to recall that it was a negative 1 and not a 255?

Link to comment
Share on other sites

Link to post
Share on other sites

6 minutes ago, Sonic7662 said:

I have a question I've been pondering for the longest time about two's complement negative numbers. I understand the theory behind two's compliment, you take a number, invert it and add 1 to get the negative equivalent of it for mathematical operations. This much makes sense to me and I can see the benefits of using it over signed values or one's complement. The problem I run into is what happens to the number when the computer wants to put it in memory. Suppose a subtraction operation is performed by the computer like 5 - 6, the result being negative 1. This would look like 11111111 in 8 bit binary, my question is what does the computer do when it stores this number in memory to recall that it was a negative 1 and not a 255?

So, your PC doesn't really subtract, it adds. So it adds 5 and -6. The result is stored in a register. So if you had an 8 bit register, it would be 11111111, but since your PC likely has 64bit register.. you get the idea on that. After the math is computed, if it's being stored to memory, then the machine stores it in some address, otgerwose, it'll do what it's supposed to do.. if it's just displayed and nothing else, then the number is output and the CPU moves on.

 

 

For ensuring proper data is retrieved, parity bits (ECC) is used to make sure the correct number of 1s are retrieved. For odd parity, the parity bit is set to 1 only if the number of 1s is even, and even parity uses a 1 bit I'd the number of 1s is odd. When data is retrieved using even parity, if the number of 1s retrieved is odd, then the CPU knows the data is corrupted.

Link to comment
Share on other sites

Link to post
Share on other sites

The computer doesn't store just 11111111, it will have a container (such as a list or register something else) that remembers whether you did that calculation using integer, long, double, unsigned int, etc etc etc.

Based on which format you used, it will know if it is signed or unsigned, and when reading back the number it will convert it appropriately.

NEW PC build: Blank Heaven   minimalist white and black PC     Old S340 build log "White Heaven"        The "LIGHTCANON" flashlight build log        Project AntiRoll (prototype)        Custom speaker project

Spoiler

Ryzen 3950X | AMD Vega Frontier Edition | ASUS X570 Pro WS | Corsair Vengeance LPX 64GB | NZXT H500 | Seasonic Prime Fanless TX-700 | Custom loop | Coolermaster SK630 White | Logitech MX Master 2S | Samsung 980 Pro 1TB + 970 Pro 512GB | Samsung 58" 4k TV | Scarlett 2i4 | 2x AT2020

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Sonic7662 said:

I have a question I've been pondering for the longest time about two's complement negative numbers. I understand the theory behind two's compliment, you take a number, invert it and add 1 to get the negative equivalent of it for mathematical operations. This much makes sense to me and I can see the benefits of using it over signed values or one's complement. The problem I run into is what happens to the number when the computer wants to put it in memory. Suppose a subtraction operation is performed by the computer like 5 - 6, the result being negative 1. This would look like 11111111 in 8 bit binary, my question is what does the computer do when it stores this number in memory to recall that it was a negative 1 and not a 255?

The value itself is stored in memory as-is. It doesn't know what kind of data type it is until the program actually acts upon it. There are flags in CPUs though to track whether or not the value is negative or positive, but it's also likely this flag is changed regardless of data type (this is probably just to make things easier)

 

What's likely happening is when the program is compiled, the compiler knows how to handle a positive or negative value, so it can create the necessary state to do negative numbers properly.

 

Not that it matters for basic math operations anyway. -1 + 1 = 0, so does 0b1111 1111 + 0b0000 0001 (assuming an 8-bit data type).

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, M.Yurizaki said:

The value itself is stored in memory as-is. It doesn't know what kind of data type it is until the program actually acts upon it. There are flags in CPUs though to track whether or not the value is negative or positive, but it's also likely this flag is changed regardless of data type (this is probably just to make things easier)

 

What's likely happening is when the program is compiled, the compiler knows how to handle a positive or negative value, so it can create the necessary state to do negative numbers properly.

 

Not that it matters for basic math operations anyway. -1 + 1 = 0, so does 0b1111 1111 + 0b0000 0001 (assuming an 8-bit data type).

 

I tend to have trouble with this explanation since, at the end of the day, a computer is effectively a dumb set of transistors that don't know up from down. So yes, you add a negative number to a positive number that results in a negative answer. Assuming the architecture is operating using two's complement, which I assume x86 does, let's say the result is again -1, which in an 8-bit system would be 1111 1111. The software running the computer calls for it to be stored on the hard drive, which the computer does. Then the power is turned off and on and the program now retrieves that number from the hard drive and adds it to the integer 3. 3 + -1 = 2, but the computer, if we were to look directly at the binary, would see 0000 0011 + 1111 1111, the result being 00000001 if I did my math correctly, how would the computer know if it was looking at a positive integer or a two's complement negative integers?

Sorry if I sound needy or arrogant, this is just one of those things that makes me curious and I can't claim to be very experienced in this area of low-level theory.

Thanks!

Link to comment
Share on other sites

Link to post
Share on other sites

19 minutes ago, Sonic7662 said:

I tend to have trouble with this explanation since, at the end of the day, a computer is effectively a dumb set of transistors that don't know up from down. So yes, you add a negative number to a positive number that results in a negative answer. Assuming the architecture is operating using two's complement, which I assume x86 does, let's say the result is again -1, which in an 8-bit system would be 1111 1111. The software running the computer calls for it to be stored on the hard drive, which the computer does. Then the power is turned off and on and the program now retrieves that number from the hard drive and adds it to the integer 3. 3 + -1 = 2, but the computer, if we were to look directly at the binary, would see 0000 0011 + 1111 1111, the result being 00000001 if I did my math correctly, how would the computer know if it was looking at a positive integer or a two's complement negative integers?

Sorry if I sound needy or arrogant, this is just one of those things that makes me curious and I can't claim to be very experienced in this area of low-level theory.

Thanks!

It's all in the status/condition flag register of the processor and what sort of action you're doing with the value. The beauty of Two's compliment is you don't need to do anything special to add or subtract values (integer multiply and divide can be done with bit shifting and adding/subbing, so that takes care of that).

 

So how does the program know it's dealing with a positive or negative number? The status/condition flag register. For example, look at the different jump instructions in the x86 architecture: http://unixwiz.net/techtips/x86-jumps.html. The way it handles negative numbers is if the sign flag is set or not. So if you had something like

 

if (foobar < 0)

In x86 assembly, it would look like

SUB EAX, 0      ; if EAX is negative, it will produce a negative result and set the sign bit
JS  some_label  ; This will jump to the label if the sign bit is set.

If you're doing some sort of printout statement, you'll probably do something similar.

 

Note that for the most part, the last operation will set the status/condition flag register. So if you load a negative number from memory into a register, it will set the sign bit if it's negative.

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, M.Yurizaki said:

It's all in the status/condition flag register of the processor and what sort of action you're doing with the value. The beauty of Two's compliment is you don't need to do anything special to add or subtract values (integer multiply and divide can be done with bit shifting and adding/subbing, so that takes care of that).

 

So how does the program know it's dealing with a positive or negative number? The status/condition flag register. For example, look at the different jump instructions in the x86 architecture: http://unixwiz.net/techtips/x86-jumps.html. The way it handles negative numbers is if the sign flag is set or not. So if you had something like

 


if (foobar < 0)

In x86 assembly, it would look like


SUB EAX, 0      ; if EAX is negative, it will produce a negative result and set the sign bit
JS  some_label  ; This will jump to the label if the sign bit is set.

If you're doing some sort of printout statement, you'll probably do something similar.

 

Note that for the most part, the last operation will set the status/condition flag register. So if you load a negative number from memory into a register, it will set the sign bit if it's negative.

 

So in this situation where the computer is loading an integer into a register:

  1. Do all of the registers used in such operations have negative flags associated with them and
  2. Is the flag bit stored alongside the value in storage/memory or does it occupy a bit outside of the value? The basis of my confusion is what happens to the value of the flag when the data needs to leave the processor on a bus without a sign bit.
Link to comment
Share on other sites

Link to post
Share on other sites

51 minutes ago, Sonic7662 said:

So in this situation where the computer is loading an integer into a register:

  1. Do all of the registers used in such operations have negative flags associated with them and
  2. Is the flag bit stored alongside the value in storage/memory or does it occupy a bit outside of the value? The basis of my confusion is what happens to the value of the flag when the data needs to leave the processor on a bus without a sign bit.

The thing with the flags is they are set regardless of what the data type is. So if the last operation results in 0b1111 1111 for an 8-bit data type, it will set the sign bit regardless if it's an unsigned value, a signed value, or a character in the source code. If you need to treat this as a unsigned value, you use a jump/branch instruction that does not use the sign flag. And again, the flags change based on the last operation. If you load a negative number from memory, it's going to set the sign bit no matter what happened previously.

 

This is why the if-statement gets compiled into two assembly instructions. There is no "if" in assembly. It's do a basic math operation (generally a subtraction) and based on what the result of the operation is (which usually checks the sign or zero flags), jump to the label or go to the next instruction.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×