I have seen these mentioned in the context of C and C++, but what is the difference between signed and unsigned variables?
Signed variables, such as signed integers will allow you to represent numbers both in the positive and negative ranges.
Unsigned variables, such as unsigned integers, will only allow you to represent numbers in the positive and zero.
Unsigned and signed variables of the same type (such as int and byte) both have the same range (range of 65,536 and 256 numbers, respectively), but unsigned can represent a larger magnitude number than the corresponding signed variable.
For example, an unsigned byte can represent values from 0 to 255, while signed byte can represent -128 to 127.
Wikipedia page on Signed number representations explains the difference in the representation at the bit level, and the Integer (computer science) page provides a table of ranges for each signed/unsigned integer type.
While commonly referred to as a 'sign bit', the binary values we usually use do not have a true sign bit.
Most computers use two's-complement arithmetic. Negative numbers are created by taking the one's-complement (flip all the bits) and adding one:
5 (decimal) -> 00000101 (binary)
1's complement: 11111010
add 1: 11111011 which is 'FB' in hex
This is why a signed byte holds values from -128 to +127 instead of -127 to +127:
1 0 0 0 0 0 0 0 = -128
1 0 0 0 0 0 0 1 = -127
- - -
1 1 1 1 1 1 1 0 = -2
1 1 1 1 1 1 1 1 = -1
0 0 0 0 0 0 0 0 = 0
0 0 0 0 0 0 0 1 = 1
0 0 0 0 0 0 1 0 = 2
- - -
0 1 1 1 1 1 1 0 = 126
0 1 1 1 1 1 1 1 = 127
(add 1 to 127 gives:)
1 0 0 0 0 0 0 0 which we see at the top of this chart is -128.
If we had a proper sign bit, the value range would be the same (e.g., -127 to +127) because one bit is reserved for the sign. If the most-significant-bit is the sign bit, we'd have:
5 (decimal) -> 00000101 (binary)
-5 (decimal) -> 10000101 (binary)
The interesting thing in this case is we have both a zero and a negative zero:
0 (decimal) -> 00000000 (binary)
-0 (decimal) -> 10000000 (binary)
We don't have -0 with two's-complement; what would be -0 is -128 (or to be more general, one more than the largest positive value). We do with one's complement though; all 1 bits is negative 0.
Mathematically, -0 equals 0. I vaguely remember a computer where -0 < 0, but I can't find any reference to it now.
Signed variables use one bit to flag whether they are positive or negative. Unsigned variables don't have this bit, so they can store larger numbers in the same space, but only nonnegative numbers, e.g. 0 and higher.
For more: Unsigned and Signed Integers
Unsigned variables can only be positive numbers, because they lack the ability to indicate that they are negative.
This ability is called the 'sign' or 'signing bit'.
A side effect is that without a signing bit, they have one more bit that can be used to represent the number, doubling the maximum number it can represent.
Signed variables can be 0, positive or negative.
Unsigned variables can be 0 or positive.
Unsigned variables are used sometimes because more bits can be used to represent the actual value. Giving you a larger range. Also you can ensure that a negative value won't be passed to your function for example.
unsigned is used when ur value must be positive, no negative value here,
if signed for int range -32768 to +32767
if unsigned for int range 0 to 65535
Unsigned variables are variables which are internally represented without a mathematical sign (plus or minus) can store 'zero' or positive values only. Let us say the unsigned variable is n bits in size, then it can represent 2^n (2 power n) values - 0 through (2^n -1). A signed variable on the other hand, 'loses' one bit for representing the sign, so it can store values from -(2^(n-1) -1) through (2^(n-1)) including zero. Thus, a signed variable can store positive values, negative values and zero.
P.S.:
Internally, the mathematical sign may be represented in one's complement form, two's complement form or with a sign bit (eg: 0 -> +, 1-> -)
All these methods effectively divide the range of representable values in n bits (2^n) into three parts, positive, negative and zero.
This is just my two cents worth.
I hope this helps.
Related
I am currently learning SQL.
When looking at the INT, I came to the understanding that an INT type is 4 bytes long, which translates to 8 bits each byte, leading to each INT being 32 bits.
However, for INT it is said that the max value for unsigned types is (2^32)-1 where the -1 is accounting for 0 value. I understand that the 32 comes from the fact that each int is 32 bits.
My question is where does the 2 come from in the calculation?
My intuition is telling me that each bit will have some sort of measure valued at 2.
int is actually a signed value in SQL. The range is from -2^31 through 2^31 - 1, which is -2,147,483,648 to 2,147,483,647. There are exactly 2^32 possible values in tis range. Note that it includes 0.
An unsigned integer would range from 0 to 2^32-1, that is up to 4,294,967,295. The - 1s are because 0 is included in the range, so the counting starts at 0 rather than 1.
The range of possible values is easily seen at with fewer bits. For instance, 3 bits can represent the values from -4 to 3:
Bits Unisgned Signed
000 0 0
001 1 1
010 2 2
011 3 3
100 4 -4
101 5 -3
110 6 -2
111 7 -1
Computers use binary system for storing values. Let's try analogy between binary and decimal system:
Consider 10-based (decimal) system. If You have number with 32 decimal places, every place having value 0-9, You have 10^32 possible values (obviously enough; we use this system on daily basis).
Now consider 2-based system, which is the one used by computers (for practical reasons - two states are easiest to distinguish and wiring logic is simplest). Every place (bit) has value 0-1, so there are 2^32 possible values.
For unsigned integers we can represent numbers ranging from
0 to 2N - 1
And for signed integers like two's complement the range is
-2(N-1) to 2(N-1) - 1
How is the signed range calculated?
For unsigned integers :
we use all N bits to represent numbers ranging from 0 to 2^N - 1 ,its because if we use all N bit positions and calculate different configuration by placing either 0 or 1 in each position, we can get at max integer 2^N - 1 (which is 11...upto N times) and lowest integer as 0 ( which is 00..upto N times). And, hence all values from 0 to 2^N - 1 can be represented.
For Signed integers :
Here we basically use N-1 bits to represent integer numbers and 1 bit is exclusively reserved for determining sign of that integer. So, we can represent numbers ranging from -2^(N-1) to 2^(N-1) - 1. The most significant bit as 1 represent the negative integers whereas most significant bit as 0 represent non negative integer values. Here, we can represent negative from -1 to -2^(N-1) from the fact that we may utilize number with all N bits as 1. Basically compilers use two's complement representation to represent integers.
Here's the deal. Let's do it for 2 bits, so N=2.
We get Range=-2 to 1, ie it can represent -2,-1,0,1.
Now if N=4, we have Range=-8 to +7.
I can't understand where are you stuck.
Here's a question I've come across:
Assume each X represents one bit, either 0 or 1. Consider the 8-bit unsigned binary numbers A = 1XXX XXXX and B = 0XXX XXXX. Which of the following are true (you may tick more than one answer):
A B > A
B A > 127
C Can't tell which one A or B is larger
D B < 127
E A > B
Explanations needed (0 understanding on this). Thanks!
The key to the answer is in the word unsigned. This means that the MSB (left most bit) is not being used to indicate the results sign. Processors perform mathematical operations such as add, subtract and comparison on numbers using twos compliment, this means that to know what the numeric value of a binary word is we must know if it is signed (can contain negative values) or unsigned (positive numbers only).
So in the above case the values are unsigned, which means A is always greater than B and that A has the MSB of an 8 bit value set to 1 so must be at least 128.
In the same way that we count in units of 10s binary works in units of two:
Binary
128 64 32 16 8 4 2 1
Decimal
1000 100 10 1
However if the binary value were signed the left most bit would be used to express positve (0) or negative (1) and when negative we need to invert the value and add one to get back to the (Negative) result.
I am trying to solve the following using two's complement in binary form.
7.5 - 6.75
7.5 - 6.75 can be rewritten as (7.5)+(-6.75)
taking binary of decimal numbers
7.5 = 111.1
6.75 = 110.11
-6.75= 001.00
Now where should I add 1, to the left of "."(period) or to the right?
To perform the subtraction of signed numbers (M – N) with 2’s complements proceed as follows:
The number of digits of M and N should be the same.
Obtain the 2’s complement of N (including the sign bit).
Add the 2’s complement of N to M (including the sign bit).
If the summation produces an end carry. Discard the end carry. After the end carry is discarded, the leftmost bit is the sign bit.
If the sign bit is 0, the result is positive,
If the sign bit is 1, the result is negative.
If the summation does not produce an end carry, the leftmost bit is the sign bit.
To Produce 2's compliment:
The 2’s complement of the subtrahend 10001 = 01111
1 1 1 1 carry bits
1 0 0 1 1
+ 0 1 1 1 1
1 0 0 0 1 0
Since the summation produces an end carry the result is positive.
Discard the end carry; the result is a positive number.
For example, if n=9, then how many different values can be represented in 9 binary digits (bits)?
My thinking is that if I set each of those 9 bits to 1, I will make the highest number possible that those 9 digits are able to represent. Therefore, the highest value is 1 1111 1111 which equals 511 in decimal. I conclude that, therefore, 9 digits of binary can represent 511 different values.
Is my thought process correct? If not, could someone kindly explain what I'm missing? How can I generalize it to n bits?
29 = 512 values, because that's how many combinations of zeroes and ones you can have.
What those values represent however will depend on the system you are using. If it's an unsigned integer, you will have:
000000000 = 0 (min)
000000001 = 1
...
111111110 = 510
111111111 = 511 (max)
In two's complement, which is commonly used to represent integers in binary, you'll have:
000000000 = 0
000000001 = 1
...
011111110 = 254
011111111 = 255 (max)
100000000 = -256 (min) <- yay integer overflow
100000001 = -255
...
111111110 = -2
111111111 = -1
In general, with k bits you can represent 2k values. Their range will depend on the system you are using:
Unsigned: 0 to 2k-1
Signed: -2k-1 to 2k-1-1
What you're missing: Zero is a value
A better way to solve it is to start small.
Let's start with 1 bit. Which can either be 1 or 0. That's 2 values, or 10 in binary.
Now 2 bits, which can either be 00, 01, 10 or 11 That's 4 values, or 100 in binary... See the pattern?
Okay, since it already "leaked": You're missing zero, so the correct answer is 512 (511 is the greatest one, but it's 0 to 511, not 1 to 511).
By the way, an good followup exercise would be to generalize this:
How many different values can be represented in n binary digits (bits)?
Without wanting to give you the answer here is the logic.
You have 2 possible values in each digit. you have 9 of them.
like in base 10 where you have 10 different values by digit say you have 2 of them (which makes from 0 to 99) : 0 to 99 makes 100 numbers. if you do the calcul you have an exponential function
base^numberOfDigits:
10^2 = 100 ;
2^9 = 512
There's an easier way to think about this. Start with 1 bit. This can obviously represent 2 values (0 or 1). What happens when we add a bit? We can now represent twice as many values: the values we could represent before with a 0 appended and the values we could represent before with a 1 appended.
So the the number of values we can represent with n bits is just 2^n (2 to the power n)
The thing you are missing is which encoding scheme is being used. There are different ways to encode binary numbers. Look into signed number representations. For 9 bits, the ranges and the amount of numbers that can be represented will differ depending on the system used.