I have created a table with a FLOAT
type column. However, I found that when I query the column's MAX
, MIN
, AVG
values I get inaccurate numbers, where the returned value is larger than what is actually stored in the table. For example, this is the actual maximum number in the table: 0.00348675. Somehow, MAX
returns this: 0.0034867459908127785
The inaccuracy turned to be due to choosing FLOAT
as type. For this reason, I want to change the columns type to DECIMAL.
I use mysql-workbench
in Ubuntu 18. When I right-click the table and choose Alter Table
I can change the data types. Unfortunately, when I change the concerned field from FLOAT
to DECIMAL
, FLOAT
returns again automatically. The workbench can not choose DECIMAL
for some reason. See this picture. I can choose DECIMAL from a list. Then when I move the mouse elsewhere to click on the next empty row, so I can click Apply
, the DECIMAL
disappear and FLOAT
returns again:
Can anyone advise me what is the reason for the prolem? how to overcome the issue?
FLOAT
and DOUBLE
are encoded in binary, not decimal. Hence, most fractional numbers cannot be represented exactly when stored. (Numbers ending with .5, .25, .75, .125, etc) can be stored exactly because they involve powers of 2.
FLOAT
is good to about 7 significant digits; DOUBLE
to about 16.
0.00348675 You stored this decimal
0.003486746000000096 After conversion to binary, then back to decimal
0.0034867459908127785 See below
(I suspect you actually stored 0.003486756
.)
Certain calculations are done in DOUBLE
; I suspect MAX()
does such. That involved converting the FLOAT
to DOUBLE
. Nothing is lost in this conversion.
OK, I am at a loss to finish the explanation.
Suffice it to say -- Whenever using FLOAT
or DOUBLE
, be aware that arithmetic and displaying have quirks like this.
There are cases where MySQL tries to avoid such problems by using DECIMAL
. I would guess that that somehow is involved here because the middle number above has about 14 significant digits, not 16, implying that something other than DOUBLE
is involved -- perhaps DECIMAL(..., 16)
. Note: that is decimal places, as distinct from significant digits_.
If you would like to pursue this further, provide a short test case in a bug filed at http://bugs.mysql.com and post the like to it here.