Ваш тестовый пример имеет недостатки.Вы вводите десятичные цифры и не тестируете просто . Передача FLOAT
в DOUBLE
.
UPDATE tbl SET double_col = float_col
всегда копирует одно и то же значение.Это потому, что представление DOUBLE
является расширенным набором представления FLOAT
(53 против 24 бит точности; и т. Д.).
Литерал с десятичными знаками: UPDATE tbl SET double_col = 123.456
будет искажать число из-за округления отдесятичное число до DOUBLE
.То же самое для float_col
.Кроме того, искаженные результаты будут другими!
Литерал номера отверстия: UPDATE tbl SET double_col = 14867199700
будет сохранен точно.Но если вы поместите тот же самый литерал в FLOAT
, он будет округлен до 24 бит, поэтому он не может быть сохранен точно.Вы теряете точность на о 7 значащих цифрах для FLOAT
и о 16 для DOUBLE
.Литерал в этом примере имеет 9 значащих цифр (после игнорирования конечных нулей).
Это просто пример кошмаров, в которые вы можете попасть.
Вы должны рассмотреть FLOAT
и DOUBLE
должны быть приблизительными .Вы никогда не должны сравнивать на равенство;вы не знаете, что могло быть с последним битом значения.
Кроме того, вы не должны пытаться угадать, когда MySQL будет выполнять выражения в DECIMAL
вместо DOUBLE
.
И имейте в виду, что деление обычно неточное из-за округления до некоторого числа бит или десятичных дробей.
"Мантисса" 14864199700 равна
1.10111010111111001101100 (binary of FLOAT : 24 bits including 'hidden' leading bit)
1.1011101011111100110110000000101000000000000000000000 (binary of DOUBLE)
^ ^ (lost in FLOAT)
Каждое из них умножаетсяпри той же степени 2. DOUBLE
получает ровно 14864199700. FLOAT
потерял указанные биты.
Вы можете поиграть с такими при https://gregstoll.dyndns.org/~gregstoll/floattohex/
Верьте илинет, раньше было хуже.Люди будут платить за 0,00 долларов из-за ошибок округления.Или результаты того, что должно было быть 1 + 1, показали как 1.99999999.