select hex(md5("anything"))%4; Why is this always zero? - mysql

Why is this always zero in mysql???
select hex(md5("anything"))%4;
I have tried replacing "anything" with anything but it's always zero.
Expect to have 0,1,2 or 3 as value but it's not showing as shown.
I would like to have (md5sum("anything") % 4). How is this possible?
Is this the best answer / solution to what I need? Does not feel right
SELECT CONV(SUBSTRING(md5('anything0-10'), 1, 15), 16, 10)%4096;

HEX() returns a string of hexadecimal digits, not a number.
mysql> select hex(md5("anything"));
+------------------------------------------------------------------+
| hex(md5("anything")) |
+------------------------------------------------------------------+
| 6630653136366463333464313464366332323866666163353736633961343363 |
+------------------------------------------------------------------+
HEX(md5('anything')) returns all decimal digits. This is NOT a coincidence. MySQL's MD5() function already returns a hex-encoded string (your calling HEX() on it is redundant). Therefore it only returns characters 0-9 and a-f:
mysql> select md5('anything');
+----------------------------------+
| md5('anything') |
+----------------------------------+
| f0e166dc34d14d6c228ffac576c9a43c |
+----------------------------------+
When you call HEX() on this string, it returns only hex values 30-39 and 61-66, encoding the ascii values of 0-9 and a-f.
This is all to explain why the long string contains only decimal digits.
When you use that string in an expression with % 4, MySQL interprets the string in a numeric context. MySQL will try to evaluate the numeric value of the string, which means reading the leading decimal digits from the string.
We can also coerce the string to a numeric context with +0:
mysql> select hex(md5('anything'))+0;
+------------------------------------------------------------------+
| hex(md5('anything'))+0 |
+------------------------------------------------------------------+
| 6630653136366463000000000000000000000000000000000000000000000000 |
+------------------------------------------------------------------+
The 64-digit number is larger than MySQL integer types can represent, so the numeric coercion must convert it to a DOUBLE value. This data type is 8 bytes, which is still not enough to represent a 64-digit number. So it rounds the value and ignores the lower digits, converting them to zeroes.
Naturally, a number ending with a bunch of zeroes is evenly divisible by 4, so modulus expression is bound to return 0.
I would like to have (md5sum("anything") % 4). How is this possible?
mysql> select conv(right(md5('anything'), 1), 16, 10) % 4 as mod4;
+------+
| mod4 |
+------+
| 0 |
+------+

My guess would be as follows:
hex(md5("anything")) returns a STRING,
% performs implicit cast to DOUBLE,
casting drops low bits
after droping two low bits, every number is a multiply of 4
For the %4 operation only the last hex digit is relevant, so you could:
get the last hex digit from the MD5 sum
convert it to base 10
perform the %4 operation
SELECT CONV(SUBSTRING(md5('anything'), -1), 16, 10)%4;

Related

How to use float type properly in mysql?

I have a table in mysql with a field type float(10, 7).
I am trying to insert value 1196.104, Even when using phpmyadmin it converts that value to 1000.0000000.
What type should I use to properly store the value 1196.104 in database.
This is working exactly as intended by the FLOAT(10,7). When you give a value that won't fit in the number of digits, it caps the value and uses the greatest value that can fit.
In this case, the 10-digit value of 999.9999999, rounded up to 1000.0000000.
https://dev.mysql.com/doc/refman/8.0/en/floating-point-types.html says:
MySQL permits a nonstandard syntax: FLOAT(M,D) or REAL(M,D) or DOUBLE PRECISION(M,D). Here, (M,D) means than values can be stored with up to M digits in total, of which D digits may be after the decimal point.
In other words, you gave it the constraint to max out at 1000.0000000, because you told it to max out at 10 digits, of which 7 digits are to the right of the decimal point.
mysql> create table f ( f float(10,7));
mysql> insert into f values (1196.104);
Query OK, 1 row affected, 1 warning (0.02 sec)
mysql> show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'f' at row 1 |
+---------+------+--------------------------------------------+
mysql> select * from f;
+--------------+
| f |
+--------------+
| 1000.0000000 |
+--------------+
If you want to store larger values, declare FLOAT with enough digits to hold the values you use. For example, the value 1196.104 could be inserted to FLOAT(11,7) or FLOAT(10,6).
Or you could use FLOAT with no arguments, and it will not constrain the number of digits at all.
There are some caveats about FLOAT. It's an inexact numeric type, and it will have rounding errors. This is unavoidable because of the way FLOAT is implemented, and it affects every programming language.
Read https://dev.mysql.com/doc/refman/8.0/en/problems-with-float.html and https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Also see my old tweet about this:
https://twitter.com/billkarwin/status/347561901460447232

mysql converting bit to char not working

I was trying to feed a result of a query as a parameter for another query and all was working fine except this field that has a datatype of bit. so i tried to convert the value of the field using convert() and cast() but it seems to be not working as its returning this wierd symbol of a small rectange which hava three 0's and a 1. so can anyone tell me why this is happening and how to fix it , here is my query
select CONVERT(isMale , char(5)) from person;
and the thing is it gives me the correct answer when i dont use the convert but since am giving this result to another query as a parameter it causing me the problem.
you can use BIN function like this:
SELECT BIN(isMale +0) from person;
sample
MariaDB [yourschema]> SELECT BIN(b'1001' +0) ;
+-----------------+
| BIN(b'1001' +0) |
+-----------------+
| 1001 |
+-----------------+
1 row in set (0.00 sec)
MariaDB [yourschema]>
Here some stuff from MariaDB Manual:
Description
Converts numbers between different number bases. Returns a
string representation of the number N, converted from base from_base
to base to_base.
Returns NULL if any argument is NULL, or if the second or third
argument are not in the allowed range.
The argument N is interpreted as an integer, but may be specified as
an integer or a string. The minimum base is 2 and the maximum base is
36. If to_base is a negative number, N is regarded as a signed number. Otherwise, N is treated as unsigned. CONV() works with 64-bit
precision.
Some shortcuts for this function are also available: BIN(), OCT(),
HEX(), UNHEX(). Also, MariaDB allows binary literal values and
hexadecimal literal values.
BIN is a short form from CONV(value,from,to) where you can convert from base to base
so binary 1001 = 9 as int
here i give the value in decimal (14) and convert it from base 10 to base 2
MariaDB [yourschema]> SELECT CONV(14,10 ,2);
+-----------------+
| CONV(14,10 ,2) |
+-----------------+
| 1110 |
+-----------------+
1 row in set (0.00 sec)
so, if you want to have 0 on the left you can add a value like this
MariaDB [yourschema]> SELECT CONV(8192 + 14,10 ,2);
+------------------------+
| CONV(8192 + 14,10 ,2) |
+------------------------+
| 10000000001110 |
+------------------------+
1 row in set (0.00 sec)
and then you can get n chars from right:
MariaDB [yourschema]> SELECT RIGHT(CONV(8192 + 14,10 ,2),8);
+---------------------------------+
| RIGHT(CONV(8192 + 14,10 ,2),8) |
+---------------------------------+
| 00001110 |
+---------------------------------+
1 row in set (0.40 sec)
MariaDB [yourschema]>
I think you want to use CAST
select CAST(isMale as CHAR) from person;
seeing #Bernd Buffen answer i tried using the convert with +0 and it works , eventhough i dont know why
select CONVERT(isMale +0, char(5)) from person;

MySQL Precison Issues in DECIMAL NUMERIC data type

In writing a function for scientific application, I ran into issues. I traced it back to MySQL's lack of precison.
Here is the page from the official documentation which claims that The maximum number of digits for DECIMAL is 65 - http://dev.mysql.com/doc/refman/5.6/en/fixed-point-types.html . It also describes how the value will be rounded if it exceeds the specified precison.
Here is reproducible code (a mysql stored function) to test it -
DELIMITER $$
DROP FUNCTION IF EXISTS test$$
CREATE FUNCTION test
(xx DECIMAL(30,25)
)
RETURNS DECIMAL(30,25)
DETERMINISTIC
BEGIN
DECLARE result DECIMAL(30,25);
SET result = 0.339946499848118887e-4;
RETURN(result);
END$$
DELIMITER ;
If you save the code above in a file called test.sql, you can run it by executing the following in mysql prompt -
source test.sql;
select test(0);
It produces the output -
+-----------------------------+
| test(0) |
+-----------------------------+
| 0.0000339946499848118900000 |
+-----------------------------+
1 row in set (0.00 sec)
As you can see, the number is getting rounded at the 20th digit, and then five zeroes are being added to it to get to the required/specified precison. That is cheating.
Am I mistaken, or is the documentation wrong?
This happens because mysql treats 0.339946499848118887e-4 as float and treats 0.0000339946499848118887 as fixed point.
mysql> select cast( 0.339946499848118887e-4 as DECIMAL(30, 25));
+----------------------------------------------------+
| cast( 0.339946499848118887e-4 as DECIMAL(30, 25)) |
+----------------------------------------------------+
| 0.0000339946499848118900000 |
+----------------------------------------------------+
1 row in set (0.00 sec)
mysql> select cast( 0.0000339946499848118887 as DECIMAL(30, 25));
+-----------------------------------------------------+
| cast( 0.0000339946499848118887 as DECIMAL(30, 25)) |
+-----------------------------------------------------+
| 0.0000339946499848118887000 |
+-----------------------------------------------------+
1 row in set (0.00 sec)
As described in the mysql documentation on precision math - expression handling -
If any approximate values are present, the expression is approximate and is evaluated using floating-point arithmetic.
Quoting from, the documentation on numerical types,
Two numbers that look similar may be treated differently. For example, 2.34 is an exact-value (fixed-point) number, whereas 2.34E0 is an approximate-value (floating-point) number.
I don't know anything about SQL, but my guess would be this line:
SET result = 0.339946499848118887e-4;
If MySQL is anything like other languages I know, then this will first evaluate the right-hand side, and then assign the value to result. No matter what type result is declared to be or what precision it's declared to have, it wouldn't matter if the right-hand side has already lost precision when being evaluated. This is almost surely what is happening here.
I can reproduce your results, but If I change that line to
SET result = cast('0.339946499848118887e-4' as decimal(30, 25));
(casting from a string instead of from a floating-point constant of unspecified precision) then I correctly get
+-----------------------------+
| test(0) |
+-----------------------------+
| 0.0000339946499848118887000 |
+-----------------------------+
1 row in set (0.00 sec)
as desired. So that's your fix.
BTW, the documentation that scale in DECIMAL(precision, scale) cannot be greater than 30 seems to be in section 12.19.2. DECIMAL Data Type Changes:
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The
ranges of values for the arguments in MySQL 5.6 are as follows:
M is the maximum number of digits (the precision). It has a range of 1
to 65. (Older versions of MySQL permitted a range of 1 to 254.)
D is the number of digits to the right of the decimal point (the
scale). It has a range of 0 to 30 and must be no larger than M.

MySQL concat() and lower() weirdness

Any idea why this works sensibly*:
mysql> select lower('AB100c');
+-----------------+
| lower('AB100c') |
+-----------------+
| ab100c |
+-----------------+
1 row in set (0.00 sec)
But this doesn't?
mysql> select lower(concat('A', 'B', 100,'C'));
+----------------------------------+
| lower(concat('A', 'B', 100,'C')) |
+----------------------------------+
| AB100C |
+----------------------------------+
1 row in set (0.00 sec)
*sensibly = 'the way I think it should work.'
As stated on MySql String functions:
LOWER(str)
LOWER() is ineffective when applied to
binary strings (BINARY, VARBINARY,
BLOB).
CONCAT(str1,str2,...)
Returns the string that results from
concatenating the arguments. May have
one or more arguments. If all
arguments are nonbinary strings, the
result is a nonbinary string. If the
arguments include any binary strings,
the result is a binary string. A
numeric argument is converted to its
equivalent binary string form; if you
want to avoid that, you can use an
explicit type cast.
In your code you are passing 100 as a numeric so concat will return a binary string and lower is ineffective when applied to binary strings that's why it's not get converted. If you want to convert you can try this:
select lower(concat('A', 'B', '100','C'));
lower is used to convert STRINGS to lowercase. But your value 100 is considered numeric. If you want to still achieve the result of lower case conversion, you should enclose the number in quotes like this:
select lower(concat('A', 'B', '100','C'));
I've tested this and it works fine.
And here is an other example with CONCAT and LIKE
LOWER(CONCAT(firstname, ' ', lastname)) LIKE LOWER('%my name%')

Difference between float and decimal data type

What difference does it make when I use float and decimal data types in MySQL?.
When should I use which?
This is what I found when I had this doubt.
mysql> create table numbers (a decimal(10,2), b float);
mysql> insert into numbers values (100, 100);
mysql> select #a := (a/3), #b := (b/3), #a * 3, #b * 3 from numbers \G
*************************** 1. row ***************************
#a := (a/3): 33.333333333
#b := (b/3): 33.333333333333
#a + #a + #a: 99.999999999000000000000000000000
#b + #b + #b: 100
The decimal did exactly what's supposed to do on this cases, it
truncated the rest, thus losing the 1/3 part.
So for sums the decimal is better, but for divisions the float is
better, up to some point, of course. I mean, using DECIMAL will not give
you a "fail proof arithmetic" in any means.
A "float" in most environments is a binary floating-point type. It can accurately store base-2 values (to a certain point), but cannot accurately store many base-10 (decimal) values. Floats are most appropriate for scientific calculations. They're not appropriate for most business-oriented math, and inappropriate use of floats will bite you. Many decimal values can't be exactly represented in base-2. 0.1 can't, for instance, and so you see strange results like 1.0 - 0.1 = 0.8999999.
Decimals store base-10 numbers. Decimal is an good type for most business math (but any built-in "money" type is more appropriate for financial calculations), where the range of values exceeds that provided by integer types, and fractional values are needed. Decimals, as the name implies, are designed for base-10 numbers - they can accurately store decimal values (again, to a certain point).
MySQL recently changed they way they store the DECIMAL type. In the past they stored the characters (or nybbles) for each digit comprising an ASCII (or nybble) representation of a number - vs - a two's complement integer, or some derivative thereof.
The current storage format for DECIMAL is a series of 1,2,3,or 4-byte integers whose bits are concatenated to create a two's complement number with an implied decimal point, defined by you, and stored in the DB schema when you declare the column and specify it's DECIMAL size and decimal point position.
By way of example, if you take a 32-bit int you can store any number from 0 - 4,294,967,295. That will only reliably cover 999,999,999, so if you threw out 2 bits and used (1<<30 -1) you'd give up nothing. Covering all 9-digit numbers with only 4 bytes is more efficient than covering 4 digits in 32 bits using 4 ASCII characters, or 8 nybble digits. (a nybble is 4-bits, allowing values 0-15, more than is needed for 0-9, but you can't eliminate that waste by going to 3 bits, because that only covers values 0-7)
The example used on the MySQL online docs uses DECIMAL(18,9) as an example. This is 9 digits ahead of and 9 digits behind the implied decimal point, which as explained above requires the following storage.
As 18 8-bit chars:
144 bits
As 18 4-bit nybbles:
72 bits
As 2 32-bit integers:
64 bits
Currently DECIMAL supports a max of 65 digits, as DECIMAL(M,D) where the largest value for M allowed is 65, and the largest value of D allowed is 30.
So as not to require chunks of 9 digits at a time, integers smaller than 32-bits are used to add digits using 1,2 and 3 byte integers. For some reason that defies logic, signed, instead of unsigned ints were used, and in so doing, 1 bit gets thrown out, resulting in the following storage capabilities. For 1,2 and 4 byte ints the lost bit doesn't matter, but for the 3-byte int it's a disaster because an entire digit is lost due to the loss of that single bit.
With an 7-bit int:
0 - 99
With a 15-bit int:
0 - 9,999
With a 23-bit int:
0 - 999,999
(0 - 9,999,999 with a 24-bit int)
1,2,3 and 4-byte integers are concatenated together to form a "bit pool" DECIMAL uses to represent the number precisely as a two's complement integer. The decimal point is NOT stored, it is implied.
This means that no ASCII to int conversions are required of the DB engine to convert the "number" into something the CPU recognizes as a number. No rounding, no conversion errors, it's a real number the CPU can manipulate.
Calculations on this arbitrarily large integer must be done in software, as there is no hardware support for this kind of number, but these libraries are very old and highly optimized, having been written 50 years ago to support IBM 370 Fortran arbitrary precision floating point data. They're still a lot slower than fixed-sized integer algebra done with CPU integer hardware, or floating point calculations done on the FPU.
In terms of storage efficiency, because the exponent of a float is attached to each and every float, specifying implicitly where the decimal point is, it is massively redundant, and therefore inefficient for DB work. In a DB you already know where the decimal point is to go up front, and every row in the table that has a value for a DECIMAL column need only look at the 1 & only specification of where that decimal point is to be placed, stored in the schema as the arguments to a DECIMAL(M,D) as the implication of the M and the D values.
The many remarks found here about which format is to be used for various kinds of applications are correct, so I won't belabor the point. I took the time to write this here because whoever is maintaining the linked MySQL online documentation doesn't understand any of the above and after rounds of increasingly frustrating attempts to explain it to them I gave up. A good indication of how poorly they understood what they were writing is the very muddled and almost indecipherable presentation of the subject matter.
As a final thought, if you have need of high-precision floating point computation, there've been tremendous advances in floating point code in the last 20 years, and hardware support for 96-bit and Quadruple Precision float are right around the corner, but there are good arbitrary precision libraries out there if manipulation of the stored value is important.
Not just specific to MySQL, the difference between float and decimal types is the way that they represent fractional values. Floating point types represent fractions in binary, which can only represent values as {m*2^n | m, n Integers} . values such as 1/5 cannot be precisely represented (without round off error). Decimal numbers are similarly limited, but represent numbers like {m*10^n | m, n Integers}. Decimals still cannot represent numbers like 1/3, but it is often the case in many common fields, like finance, that the expectation is that certain decimal fractions can always be expressed without loss of fidelity. Since a decimal number can represent a value like $0.20 (one fifth of a dollar), it is preferred in those situations.
decimal is for fixed quantities like money where you want a specific number of decimal places. Floats are for storing ... floating point precision numbers.
mysql> CREATE TABLE num(id int ,fl float,dc dec(5,2));
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO num VALUES(1,13.75,13.75);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO num VALUES(2,13.15,13.15);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM num WHERE fl = 13.15;
Empty set (0.00 sec)
mysql> SELECT * FROM num WHERE dc = 13.15;
+------+-------+-------+
| id | fl | dc |
+------+-------+-------+
| 2 | 13.15 | 13.15 |
+------+-------+-------+
1 row in set (0.00 sec)
mysql> SELECT SUM(fl) ,SUM(dc) FROM num;
+--------------------+---------+
| SUM(fl) | SUM(dc) |
+--------------------+---------+
| 26.899999618530273 | 26.90 |
+--------------------+---------+
1 row in set (0.00 sec)
mysql> SELECT * FROM num WHERE ABS(fl - 13.15)<0.01;
+------+-------+-------+
| id | fl | dc |
+------+-------+-------+
| 2 | 13.15 | 13.15 |
+------+-------+-------+
1 row in set (0.00 sec)
I found this useful:
Generally, Float values are good for scientific Calculations, but should not be used for Financial/Monetary Values. For Business Oriented Math, always use Decimal.
Source: http://code.rohitink.com/2013/06/12/mysql-integer-float-decimal-data-types-differences/
If you are after performance and not precision, you should note that calculations with floats are much faster than decimals
Floating-Point Types (Approximate Value) - FLOAT, DOUBLE
The FLOAT and DOUBLE types represent approximate numeric data values. MySQL uses four bytes for single-precision values and eight bytes for double-precision values.
For FLOAT, the SQL standard permits an optional specification of the precision (but not the range of the exponent) in bits following the keyword FLOAT in parentheses. MySQL also supports this optional precision specification, but the precision value is used only to determine storage size. A precision from 0 to 23 results in a 4-byte single-precision FLOAT column. A precision from 24 to 53 results in an 8-byte double-precision DOUBLE column.
MySQL permits a nonstandard syntax: FLOAT(M,D) or REAL(M,D) or DOUBLE PRECISION(M,D). Here, “(M,D)” means than values can be stored with up to M digits in total, of which D digits may be after the decimal point. For example, a column defined as FLOAT(7,4) will look like -999.9999 when displayed. MySQL performs rounding when storing values, so if you insert 999.00009 into a FLOAT(7,4) column, the approximate result is 999.0001.
Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies.
For maximum portability, code requiring storage of approximate numeric data values should use FLOAT or DOUBLE PRECISION with no specification of precision or number of digits.
https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html
Problems with Floating-Point Values
Floating-point numbers sometimes cause confusion because they are approximate and not stored as exact values. A floating-point value as written in an SQL statement may not be the same as the value represented internally. Attempts to treat floating-point values as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies. The FLOAT and DOUBLE data types are subject to these issues. For DECIMAL columns, MySQL performs operations with a precision of 65 decimal digits, which should solve most common inaccuracy problems.
The following example uses DOUBLE to demonstrate how calculations that are done using floating-point operations are subject to floating-point error.
mysql> CREATE TABLE t1 (i INT, d1 DOUBLE, d2 DOUBLE);
mysql> INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
-> (2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
-> (2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
-> (4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
-> (5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
-> (6, 0.00, 0.00), (6, -51.40, 0.00);
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
-> FROM t1 GROUP BY i HAVING a <> b;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
| 6 | -51.4 | 0 |
+------+-------+------+
The result is correct. Although the first five records look like they should not satisfy the comparison (the values of a and b do not appear to be different), they may do so because the difference between the numbers shows up around the tenth decimal or so, depending on factors such as computer architecture or the compiler version or optimization level. For example, different CPUs may evaluate floating-point numbers differently.
If columns d1 and d2 had been defined as DECIMAL rather than DOUBLE, the result of the SELECT query would have contained only one row—the last one shown above.
The correct way to do floating-point number comparison is to first decide on an acceptable tolerance for differences between the numbers and then do the comparison against the tolerance value. For example, if we agree that floating-point numbers should be regarded the same if they are same within a precision of one in ten thousand (0.0001), the comparison should be written to find differences larger than the tolerance value:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) > 0.0001;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 6 | -51.4 | 0 |
+------+-------+------+
1 row in set (0.00 sec)
Conversely, to get rows where the numbers are the same, the test should find differences within the tolerance value:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
-> GROUP BY i HAVING ABS(a - b) <= 0.0001;
+------+------+------+
| i | a | b |
+------+------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
+------+------+------+
5 rows in set (0.03 sec)
Floating-point values are subject to platform or implementation dependencies. Suppose that you execute the following statements:
CREATE TABLE t1(c1 FLOAT(53,0), c2 FLOAT(53,0));
INSERT INTO t1 VALUES('1e+52','-1e+52');
SELECT * FROM t1;
On some platforms, the SELECT statement returns inf and -inf. On others, it returns 0 and -0.
An implication of the preceding issues is that if you attempt to create a replication slave by dumping table contents with mysqldump on the master and reloading the dump file into the slave, tables containing floating-point columns might differ between the two hosts.
https://dev.mysql.com/doc/refman/5.5/en/problems-with-float.html
Hard & Fast Rule
If all you need to do is add, subtract or multiply the numbers you are storing, DECIMAL is best.
If you need to divide or do any other form of arithmetic or algebra on the data you're almost certainly going to be happier with float. Floating point libraries, and on Intel processors, the floating point processor itself, have TONs of operations to correct, fix-up, detect and handle the blizzard of exceptions that occur when doing typical math functions - especially transcendental functions.
As for accuracy, I once wrote a budget system that computed the % contribution of each of 3,000+ accounts, for 3,600 budget units, by month to that unit's consolidation node, then based on that matrix of percentages (3,000 + x 12 x 3,600) I multiplied the amounts budgeted by the highest organizational nodes down to the next 3 levels of the organizational nodes, and then computed all (3,000 + 12) values for all 3,200 detail units from that. Millions and millions and millions of double precision floating point calculations, any one of which would throw off the roll-up of all of those projections in a bottoms-up consolidation back to the highest level in the organization.
The total floating point error after all of those calculations was ZERO. That was in 1986, and floating point libraries today are much, much better than they were back then. Intel does all of it's intermediate calculations of doubles in 80 bit precision, which all but eliminates rounding error. When someone tells you "it's floating point error" it's almost certainty NOT true.
float (and double) represents binary fractions
decimal represents decimal fractions
declare #float as float(10)
declare #Decimal as decimal(10)
declare #Inetger as int
set #float =10.7
set #Decimal =10.7
set #Inetger=#Decimal
print #Inetger
in float when set value to integer print 10
but in decimal 11