2016-08-19 2 views
-1

Это несколько связано с answer. Я понимаю, что float не рекомендуется для высокой точности. Но я не совсем получить то, что происходит с FLOAT после прохождения ниже результатов,Что происходит с поплавком Mysql?

Наблюдения 1

Значение, возвращенное ниже 2 запросов возвращает различные результаты,

SELECT MY_FLOAT_COL FROM MY_TABLE; 

SELECT MY_FLOAT_COL*1 FROM MY_TABLE; 

Возможное объяснение - ссылка в приведенной выше ссылке, в которой говорится, что поплавок является приблизительным значением, а проблема связана с типом данных.

Наблюдение 2

Запросы

SELECT MY_FLOAT_COL*1 FROM MY_TABLE; 

SELECT MY_FLOAT_COL FROM MY_TABLE; 

возвращает тот же результат, когда я выполняю с помощью Белка SQL (Java), но возвращает разные результаты при выполнении через Хайди SQL (Object Pascal) и Python скрипт. Таким образом, это приводит к выводу, что проблема связана с клиентом.

Что именно происходит с типом Float Mysql. Я пытаюсь понять выше 2 наблюдений.

Редактировать: Мне больше не нравится мое Наблюдение 2. Я могу сделать какой-то смысл из своего Observation 1, но последний таинственный на данный момент.

+0

Различные SQL двигатели реализовать некоторые вещи по-разному. Какой у Вас вопрос? –

+0

Все наблюдения находятся на одном сервере. Мой вопрос в том, что, как упоминалось, пытаясь осмыслить наблюдение ... – Kannan

ответ

2

При умножении на 1 результат преобразуется в DOUBLE. Это имеет более высокую точность, и в результате вы можете увидеть ошибку в десятичном приближении. Вы можете видеть то же самое, назначив столбец FLOAT столбцу DOUBLE.

CREATE TABLE `my_table` (
    `my_float_col` float, 
    `my_double_col` double 
); 
INSERT INTO my_table (my_float_col) values (1.2355); 
UPDATE my_table SET my_double_col = my_float_col; 
SELECT my_float_col, my_double_col, my_float_col * 1 FROM my_table; 
+--------------+--------------------+--------------------+ 
| my_float_col | my_double_col  | my_float_col * 1 | 
+--------------+--------------------+--------------------+ 
|  1.2355 | 1.2354999780654907 | 1.2354999780654907 | 
+--------------+--------------------+--------------------+ 

Я не совсем уверен, почему это возвращение DOUBLE от умножения, потому что documentation говорит:

Если какой-либо из операндов +, -, /, *, % является реальное или строковое значение, точность результата - точность операнда с максимальной точностью.

Но это явно то, что происходит.

+0

Бармар, я думаю, что дело было решено с помощью справочной страницы тайны, которую я раскопал. – Drew

+0

Рад, что я смог поставить вас на правильный путь. – Barmar

+0

Вы всегда делаете Barmar: p – Drew

2

Происходящее можно объяснить с небольшим изменением в ответ Barmar, который у меня есть ниже:

drop table if exists my_table2; 
CREATE TABLE `my_table2` (
    `my_float_col` float(18,16), -- FLOAT(M,D) 
    `my_double_col` double(18,16) 
); 
INSERT INTO my_table2 (my_float_col) values (1.2355); -- 1.2354999780654907 
UPDATE my_table2 SET my_double_col = my_float_col; 
SELECT my_float_col, my_double_col, my_float_col * 1 FROM my_table2; 
+--------------------+--------------------+--------------------+ 
| my_float_col  | my_double_col  | my_float_col * 1 | 
+--------------------+--------------------+--------------------+ 
| 1.2354999780654907 | 1.2354999780654907 | 1.2354999780654907 | 
+--------------------+--------------------+--------------------+ 

Поплавок (колонка 1) для Barmar является C поплавок типа данных так же, как шахта. Но поскольку он не указывал точность (M,D), внутренняя реализация в C по-прежнему привязывает его к C float, мы имеем то же значение, но факт теряется в Barmar's. Просто его ширина экрана округляет его. Обратите внимание на функцию, созданную ниже, которая может это показать.

И ознакомьтесь с этой юмористической страницей руководства MySQL под названием FLOAT and DOUBLE Data Type Representation, и я думаю, что всем будет понятно, кому это нужно. Потому что мы, Afterall, быть математические головки в любом случае:

Давайте теперь взять эту историю, откуда MySQL Справочное руководство кончает.

Следующая дискуссия сосредоточена на том случае, когда нет отображения ширины и десятичного знака. Это означает, что FLOAT хранится как независимо от того, какой тип плавающего типа C и REAL или DOUBLE [ТОЧНОСТЬ] сохранен , как и любой тип C. Длина поля выбирается кодом MySQL .

Так, несмотря на первый столбец Barmar о выходе, он никогда не был там как 1.2355 и выше страничное руководство умно и юмористически описывает голова стучали, что люди пережили.

Helper СКЛС если интерес:

DROP FUNCTION IF EXISTS returnFloatFromDec; 
DELIMITER $$ 
CREATE FUNCTION returnFloatFromDec(n DECIMAL(18,16)) 
returns FLOAT 
BEGIN 
    DECLARE theRet FLOAT; 
    SET theRet=n; -- note that CAST can't take a FLOAT 
    return(theRet); 
END;$$ 
DELIMITER ; 
+0

Спасибо за детали. Но все же я не могу рассуждать о своем наблюдении 2. – Kannan

+0

Очень ясно, что данные хранятся как поплавок С, и это проблема с отображением. Вышеупомянутая ссылка ссылается на нее – Drew

Смежные вопросы