What is the difference between signed and unsigned in MySQL? And what does signed and unsigned mean?
Unsigned numbers do not have the minus sign. Unsigned number can be only positive or zero (e.g. 123, 0). Signed numbers can be also negative (e.g. -42).
This answer explains the difference throughly.
The range that you can store in a given space. E.g., quoting from the docs:
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
A very small integer. The signed range
is -128 to 127. The unsigned range is
0 to 255.
and similarly of course for other larger integer types.
Range of possible values, as seen on this table.
It's not specific to MySQL, it is a consequence of how integers are represented in a computer. Sign takes one bit for itself, thus the maximum number gets (roughly) halved. You can also think of it like shifting the whole thing by half the range downwards. (Also, because there's an even number of available numbers and there aren't two zeroes, you get one more negative number than positive). If you want to know more, read up on two's complement.
Related
I am writing a generic routine for converting fixed-point numbers between decimal and binary representations.
For positive numbers the processing is simple, however when things come to negative ones I found divergent sources. Someone says there is a single bit used to hold the sign while others say the whole number should be represented in a pseudo integer using 2's complement even it is negative.
Please anyone tell me which source is correct or is there a standard representation for signed fixed point numbers?
Additionally, if the 2's complement representation was correct then how to represent negative numbers with zero integer part. For example -0.125?
Fixed-point numbers are just binary values where the place values have been changed. Assigning place values to the bits is an arbitrary human activity, and we can do it in any way that makes sense. Normally we talk about binary integers so it is convenient to assign the place value 2^0 = 1 to the LSB, 2^1=2 to the bit to the left of the LSB, and so on. For an N bit integer the place value of the MSB becomes 2^(N-1). If we want a two's-complement representation, we change the place value of the MSB to -2^(N-1) and all of the other bit place values are unchanged.
For fixed-point values, if we want F bits to represent a fractional part of the number, then the place value of the LSB becomes 2^(0-F)
and the place value of the MSB becomes 2^(N-1-F) for unsigned numbers and -2^(N-1-F) for signed numbers.
So, how would we represent -0.125 in a two's-complement fixed-point value? That is equal to 0.875 - 1, so we can use a representation where the place value of the MSB is -1 and the value of all of the other bits adds up to 0.875. If you choose a
4-bit fixed-point number with 3 fraction bits you would say that
1111 binary equals -0.125 decimal. Adding up the place values of the bits we have (-1) + 0.5 + 0.25 + 0.125 = -0.125. My personal preference is to write the binary number as 1.111 to note which bits are fraction and which are integer.
The reason we use this approach is that the normal integer arithmetic operators still work.
It's easiest to think of fixed-point numbers as scaled integers — rather than shifted integers. For a given fixed-point type, there is a fixed scale which is a power of two (or ten). To convert from the real value to the integer representation, multiply by that scale. To convert back again, simply divide. Then the issue of how negative values are represented becomes a detail of the integer type with which you are representing your number.
Please anyone tell me which source is correct...
Both are problematic.
Your first source is incorrect. The given example is not...
the same as 2's complement numbers.
In two’s complement, the MSB's (most significant bit's) weight is negated but the other bits still contribute positive values. Thus a two’s complement number with all bits set to 1 does not produce the minimum value.
Your second source could be a little misleading where it says...
shifting the bit pattern of a number to the right by 1 bit always divide the number by 2.
This statement brushes over the matter of underflow that occurs when the LSB (least significant bit) is set to 1, and the resultant rounding. Right-shifting commonly results in rounding towards negative infinity while division results in rounding towards zero (truncation). Both produce the same behavior for positive numbers: 3/2 == 1 and 3>>1 == 1. For negative numbers, they are contrary: -3/2 == -1 but -3>>1 == -2.
...is there a standard representation for signed fixed point numbers?
I don't think so. There are language-specific standards, e.g. ISO/IEC TR 18037 (draft). But the convention of scaling integers to approximate real numbers of predetermined range and resolution is well established. How the underlying integers are represented is another matter.
Additionally, if the 2's complement representation was correct then how to represent negative numbers with zero integer part. For example -0.125?
That depends on the format of your integer and your choice of radix. Assuming a 16-bit two’s complement number representing binary fixed-point values, the scaling factor is 2^15 which is 32,768. Multiply the value to store as an integer: -0.125*32768. == -4096 and divide to retrieve it: -4096/32768. == -0.125.
According to the MySQL Numeric types documentation, among other, Float types have these properties:
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
A small (single-precision) floating-point number. Permissible values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38. These are the theoretical limits, based on the IEEE standard. The actual range might be slightly smaller depending on your hardware or operating system.
M is the total number of digits and D is the number of digits following the decimal point. If M and D are omitted, values are stored to the limits permitted by the hardware. A single-precision floating-point number is accurate to approximately 7 decimal places.
UNSIGNED, if specified, disallows negative values.
I want to determine if the behavior of unsigned float is similar to the behavior of unsigned int where the the full bit depth of the decimal and mantissa is used to represent positive values, or if unsigned floats only prevent negative values.
I want to determine if the behavior of unsigned float is similar to
the behavior of unsigned int where the the full bit depth of the
decimal and mantissa is used to represent positive values, or
No. MySQL chose to use IEEE-754 Single precision Float for its FLOAT. IEEE Float is "sign-magnitude", so the sign bit occupies a specific location of its own. INT, on the other hand, is 2's complement encoding. So, the bit for the sign can be either interpreted as a sign or as an extension of the value. (Caveat: Virtually all current computer hardware works the way described in this paragraph; but there may be some that do not. An antique example: The CDC 6600 used 1's complement.)
if unsigned floats only prevent negative values.
Yes.
It has to be said: If you're using the inherently imprecise FLOAT data type you should think through why your problem space prohibits all negative numbers. Do those numbers faithfully represent the problem space? Is FLOAT's imprecision acceptable for what you're representing?
The idea that there can be no computation on floating-point numbers is illusory. Just generating them from integers involves computation. Yes, it's done directly on the computer chip, but it's still computation.
And, the example of packet loss is
precisely represented by two integers: number of packets lost / number of packets (you could call this a rational number if you wanted), or
approximately represented by a FLOAT fraction resulting from dividing one of those integers by the other.
With respect, you're overthinking this.
FLOAT always occupies 4 bytes, regardless of the options tacked onto it. DECIMAL(m,n), on the other hand, occupies approx (m/2) bytes.
FLOAT(m,n), is probably useless. The n says to round in decimal to n places, then store into a binary number (IEEE Float), thereby causing another rounding.
Here are two slightly different definitions of DT_NUMERIC from msdn
An exact numeric value with a fixed precision and scale. This data type is a 16-byte unsigned integer with a separate sign, a scale of 0 - 38, and a maximum precision of 38.
An exact numeric value with a fixed precision and scale. This data type is a 16-byte value with a separate sign, a scale of 0 to 38, and a maximum precision of 38.
What does separate sign mean?
Is it signed or not?
If it is not signed, how to indicate it is with this 'separate sign'?
DT_NUMERIC is SIGNED. You're right, the definition of "separate sign" is not very clear! But you can put a signed integer in such a field and it will work.
5 (decimal) in binary 00000101
-5 (two's complement) in binary 11111011
but 11111011 is also 251 (decimal)!
How does computer discern one from another??
How does it know whether it's -5 or 251??
it's THE SAME 11111011
Thanks in advance!!
Signed bytes have a maximum of 127.
Unsigned bytes cannot be negative.
The compiler knows whether the variable holding that value is of signed or unsigend type, and treats it appropriately.
If your program chooses to treat the byte as signed, the run-time system decides whether the byte is to be considered positive or negative according to the high-order bit. A 1 in that high-order bit (bit 7, counting from the low-order bit 0) means the number is negative; a 0 in that bit position means the number is positive. So, in the case of 11111011, bit 7 is set to 1 and the number is treated, accordingly, as negative.
Because the sign bit takes up one bit position, the absolute magnitude of the number can range from 0 to 127, as was said before.
If your program chooses to treat the byte as unsigned, on the other hand, what would have been the sign bit is included in the magnitude, which can then range from 0 to 255.
Two's complement is designed to allow signed numbers to be added/substracted to one another in the same way unsigned numbers are. So there are only two cases where the signed-ness of numbers affect the computer at low level.
when there are overflows
when you are performing operations on mixed: one signed, one unsigned
Different processors take different tacks for this. WRT orverflows, the MIPS RISC architecture, for example, deals with overflows using traps. See http://en.wikipedia.org/wiki/MIPS_architecture#MIPS_I_instruction_formats
To the best of my knowledge, mixing signed and unsigned needs to avoided at a program level.
If you're asking "how does the program know how to interpret the value" - in general it's because you've told the compiler the "type" of the variable you assigned the value to. The program doesn't actually care if 00000101 as "5 decimal", it just has an unsigned integer with value 00000101 that it can perform operations legal for unsigned integers upon, and will behave in a given manner if you try to compare with or cast to a different "type" of variable.
At the end of the day everything in programming comes down to binary - all data (strings, numbers, images, sounds etc etc) and the compiled code just ends up as a large binary blob.
My table has few fields with an amount column of type decimal.
This column will have either a deposited amount (a positive value) or a withdraw amount (a negative value).
I store the positive value as just 120 and the negative value as -50.
I sum the column and got the result as expected.
Mysql version is: 5.1.33-community.
When i checked mysql documentation about decimal i confused with their description.
Before MySQL 5.0.3, if you inserted
+0003.1 into a DECIMAL(5,1) column, it was stored as +0003.1. As of MySQL
5.0.3, it is stored as 3.1. For negative numbers, a literal -
character is no longer stored.
Applications that rely on the older
behavior must be modified to account
for this change. http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html
When i listed the rows in phpmyadmin i could see the negative sign and when i calculated the result was as expected. but the documentation said no sign will appear.
Is it good to store negative number in decimal(haven't i studied in school? confused)?... or do we have to use float.
I learn't that float would complicate calculations and was advised to stick with decimal for certain conditions.
I would like to have suggestions for this.
From what I understand, the documentation is saying it won't store a literal "-" character, which means it's probably now doing what the other signed INTEGER fields have always done and it's storing a sign bit to denote negative numbers instead.
You're still seeing a minus sign preceding the number because it's being generated by MySQL as a result of that sign bit.
If you don't understand the sign bit, you can consider how a signed byte can store numbers from -128 to 127, while an unsigned byte can store numbers from 0 to 255. That's because one of the 8 bits in a signed number is being used to store +/- (1 is negative, 0 is positive), while the remaining bits offer numbers up to 2^7 (-128 or 127).
So, for example, if the bits 1111 had a sign bit they would equal -7 (negative+4+2+1), but if they were unsigned they'd equal 15 (8+4+2+1). It's still the same amount of bits being stored.
You may wonder why the negative bound in a signed number can use the 8th bit, while the positive bound is limited to the sum of the 7 bits (1 less than the 8th bit). This is because 10000000 is considered to be both negative and the 8th bit simultaneously, because its representation of -0 otherwise is redundant with 00000000 which represents 0. There's no distinction between negative and positive zero, so a negative most significant bit is always the value of that bit itself (but negative).