I have the following sql query in mysql:
SELECT *
FROM _t_test
WHERE pret NOT
IN ( 2.6700, 2.6560, 1.8200 )
I would expect the rows with the value 1.8200 not to be shown, yet I still get them.
Am I missing something?
The field "pret" is double(16,4).
This is a rounding error. A double is not an exact value, so 1.8200 isn't represented exactly, so the values are not exactly the same.
For MYSQL floating points, see http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
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
See http://en.wikipedia.org/wiki/Double_precision_floating-point_format
Related
Database field name with datatype value float(5,2)
Inserted value
7.80
78.00
My query in modal
$checkValue = static::find()->where(['value' => $this->value])->one();
If i passed $this->valueequal to 78.00 or 78.000 then it returns proper result.
But if I pass 7.80 or 7.8 then 0 rows are returned. Why?
i suspect internally mysql treats 7.8 as something like 7.800000000001 so you cannot get a result if you compare with a fixed value.
you may have come across mysql's reference manuals on datatypes.
please note the following:
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 more information, see Section B.5.4.8, “Problems with Floating-Point Values”
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.
for most applications you can safely use a fixed point type.
essentially using decimal(5,2) instead of float(5,2) ensuring that any value displayed is the exact value stored internally.
when applicable rounding happens on insert with the "round half up" rule to the precision you specifed and is somewhat more intuitive and easy to manage
I resolve this issue with double datatype
value double(5,2)
I have a question about a query that I'm running on a MySQL Server (v5.5.50-0+deb8u1).
SELECT 12 - (SELECT qty FROM Table WHERE id = 5213) AS Amount
so Amount value is 12 - 8,5500000000000007 = 3.4499999999999993
But if I run the query:
SELECT qty FROM Table WHERE id = 5213
it returns 8.55 that is the correct number written in the record, so I was expecting that the first querty returned 3.45.
The "qty" column in the table "Table" is a DOUBLE.
How is it possibile? How can I get the right answer from the query?
thanks in advance
Well that's just the way floating numbers are.
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.
This statement holds true for many programming languages as well. Some numbers don't even have an exact representation. Here's something from the python manual
The problem is easier to understand at first in base 10. Consider the
fraction 1/3. You can approximate that as a base 10 fraction:
0.3 or, better,
0.33 or, better,
0.333 and so on. No matter how many digits you’re willing to write down, the result will never be exactly 1/3, but will be an
increasingly better approximation of 1/3.
In the same way, no matter how many base 2 digits you’re willing to
use, the decimal value 0.1 cannot be represented exactly as a base 2
fraction. In base 2, 1/10 is the infinitely repeating fraction
So in short generally doing is float1 = float2 type of comparison is a bad idea but everyone keeps forgetting it.
You can define 'qty' column as decimal(10,2)
I have a simple float column, that doesn't yield the correct value when selected via a CASE:
SELECT my_column FROM my_table LIMIT 1; yields 815.35
But SELECT (CASE WHEN true THEN my_column ELSE 0 END) AS my_column FROM my_table LIMIT 1; yields 815.3499755859375
Problem is obviously coming from the case and from the ELSE value (using 'test' rather than 0 works as intended, but using an other float does not)
I could solve it by using ROUND(my_column,2), or using a decimal column instead of a float one, but I'd actually want to understand what's happening here
I think #dasblinkenlight has explained the underlying issue with the representation. Your question is also about the CASE.
A CASE expression returns a single type. MySQL has to decide on the type when the query is compiled.
Your CASE is combining two different types, a float and an int. I believe that this should be returning a float value.
The rules leave me a bit confused as to why anything is happening; after all, a float to a float sounds like a no-op. But, there are two representations for floats, 4-byte and 8-byte. My guess is that your column is stored as a 4-byte float. The SQL engine decides that the CASE expression should return an 8-byte double. The conversion to the double is the cause of your issue.
In fact, this little SQLFiddle confirms this guess. The issue is a conversion to double.
The value 815.35 has no exact representation as IEEE-754 float. The value that is actually stored in a float field is an approximation that depends on the number of bits used for the representation.
When you use single-precision float, the value becomes 815.3499755859375, which is what you see printed when you run the query. You can compute the representation that you get with an IEEE-754 calculator (for example, this one).
In order to avoid representation differences like this, use decimal data ty[e to represent values that need precise decimal representation, such as amounts of money.
I spotted some rounding bug in MySQL. Here is my query:
SELECT /*debugz*/ ROUND((SUM(grade)/2),0) AS grade, SUM(grade) FROM entry.computed_grade a WHERE a.stud_id='7901159' AND a.sy='2014' AND a.term=01 AND a.terms=01 AND a.catalog_no='Christian Life Formation';
and the result is this:
grade sum(grade)
------ ------------
92 185
The grade result should be 93, not 92 because 185/2 = 92.5
Try this
SELECT CEIL((SUM(grade)/2),0) AS grade, SUM(grade) FROM entry.computed_grade a WHERE ((a.stud_id='7901159') AND (a.sy='2014') AND (a.term=01) AND (a.terms=01) AND (a.catalog_no='Christian Life Formation'));
Try to use ceil instead of round.
e.g ceil(1.45) = 2
You should check rounding behavior artickle for mysql. I believe here is the reason of your problem:
For approximate-value numbers, the result depends on the C library. On
many systems, this means that ROUND() uses the “round to nearest even”
rule: A value with any fractional part is rounded to the nearest even
integer.
By the way it's IEEE standard for float point rounding, so you might want stay with it
Do not "patch" this problem by tweaking the query. Actually fix your database. If you are not storing the "grade" column as the DECIMAL data type, and are instead using FLOAT or DOUBLE, your design is inherently broken.
Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems.
http://dev.mysql.com/doc/refman/5.6/en/floating-point-types.html
This is not a bug in MySQL. It is an inherent limitation in industry-standard floating point number storage. Use DECIMAL columns to store meaningful, precise numbers, and the other two types only when low storage space or a wide range of allowable values are more important than precision.
Why Subtraction of two equal values in mysql does not equal zero?
both field type are double. See image below
That's known as a approximate precision . This isn't an error, floating point data types are intended to work such way. They can not store data precisely. So if that matters, you should use fixed-point data types, such as DECIMAL in MySQL.
On the other hand, you can always use precision delta for comparisons for floating point, like:
SELECT
`foo`,
`bar`,
IF(ABS(`foo`-`bar`)<1E-13, 0, `foo`-`bar`) AS zero_compared
FROM
t
as you can see, here delta is 1E-13 (normally, that will be enough)
This problem is due to floating point precision and calculations on them.
You can also refer this Issue for clarity on your problem:
MySQL floating point comparison issues