Тип данных MySql FLOAT и проблемы с 7-значной - PullRequest
4 голосов
/ 22 мая 2009

Мы используем MySql 5.0 в Ubuntu 9.04. Полная версия: 5.0.75-0ubuntu10

Я создал тестовую базу данных. и тестовая таблица в нем. Я вижу следующий вывод из оператора вставки:

mysql> CREATE TABLE test (floaty FLOAT(8,2)) engine=InnoDb;
Query OK, 0 rows affected (0.02 sec)

mysql> insert into test value(858147.11);
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM test;
+-----------+
| floaty    |
+-----------+
| 858147.12 | 
+-----------+
1 row in set (0.00 sec)

Кажется, есть проблема с настройкой масштаба / точности в mySql ... или я что-то пропустил?

UPDATE:

Найдена граница для одного из чисел, которое мы вставили, вот код:

mysql> CREATE TABLE test (floaty FLOAT(8,2)) engine=InnoDb;
Query OK, 0 rows affected (0.03 sec)

mysql> insert into test value(131071.01);
Query OK, 1 row affected (0.01 sec)

mysql> insert into test value(131072.01);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM test;
+-----------+
| floaty    |
+-----------+
| 131071.01 | 
| 131072.02 | 
+-----------+
2 rows in set (0.00 sec)

mysql> 

Ответы [ 2 ]

11 голосов
/ 22 мая 2009

Лицо Ладони !!!!

Плавающие числа - это 32-битные числа, хранящиеся как мантисса и экспоненты. Я не уверен на 100%, как MySql разделит хранилище, но, взяв в качестве примера Java, они будут использовать 24 бита для подписанной мантиссы и 8 бит для экспоненты (научная запись). Это означает, что максимальное значение, которое может иметь FLOAT, равно + 8388608 * 10 ^ 127, а минимальное -8388608 * 10 ^ 127. Это означает только 7 значащих цифр, и мое определение FLOAT использовало 8.

Мы собираемся переключить все эти 8,2 на DOUBLE с FLOAT.

1 голос
/ 22 мая 2009

В документации по MySQL упоминается «MySQL выполняет округление при сохранении значений», и я подозреваю, что это проблема здесь. Я продублировал вашу проблему, но изменил тип хранилища на DOUBLE:

CREATE TABLE test (val, DOUBLE);

и полученное значение соответствует указанному вами тесту.

Мое предложение, для чего бы это ни стоило, это использовать DOUBLE или, возможно, DECIMAL. Я попробовал тот же самый оригинальный тест с:

CREATE TABLE test (val, DECIMAL(8,2));

и он получил значение, которое я ему дал: 858147.11.

...