проблема точности с плавающей точкой в ​​MySQL - PullRequest
4 голосов
/ 23 декабря 2010

Может ли кто-нибудь, приведенный ниже пример, дать мне объяснение, как FLOAT работает в mySQL? Я знаю, что поплавок является приблизительным, но на самом деле, такая разница? И там только 9 цифр, так что это не проблема переполнения, не так ли?

mysql> create table t(f FLOAT(15,2), db DOUBLE);
mysql> insert into t(f,db) VALUES (512659663, 512659663);
mysql> select * from t;

+--------------+-----------+
| f            | db        |
+--------------+-----------+
| 512659648.00 | 512659663 |
+--------------+-----------+

(mysql Ver 14.14 Distrib 5.1.44, для Win32 (ia32) в Windows XP)

Ответы [ 3 ]

13 голосов
/ 23 декабря 2010

FLOAT - это 32 -битный тип с, как следует из названия, с плавающей точкой.Чем выше значение, тем меньше абсолютная точность.

512659648 достаточно велико, чтобы вводить ошибки в десятках.

Update:

In IEEE-754(это то, чем является FLOAT), данные хранятся в 32 битах: 1 -битном знаке, 8 -битном двоичном показателе и 23 -битном значении.

Показатель степени показываетвы ближайшая наименьшая сила 2 (28 в вашем случае или 268435456).

Значение и представляет собой двоичную дробь.Он может хранить числа от 1 до 2 с точностью до 2^-23.В вашем случае это 1.11101000111010010000110 или ~ 1.9098060 в десятичной записи.

Число рассчитывается как произведение показателя степени и значения.

Учитывая все это, точность равна 2 ^ (28 - 23) = 2 ^ 5 = 32 для номеров этого заказа (2^28 до 2^29).

1 голос
/ 23 декабря 2010

Мантисса с плавающей запятой с одинарной точностью имеет длину 22 бита. Поэтому он не может точно хранить целое число больше 2 ^ 22, 4194304.

1 голос
/ 23 декабря 2010

На самом деле, в MySQL FLOAT и DOUBLE являются приблизительными числами с плавающей точкой. MySQL использует четыре байта для значений одинарной точности и восемь байтов для значений двойной точности.

Итак, оба столбца являются приблизительными - просто ваш столбец FLOATполучает 4 байта, чтобы попытаться приблизить ваш номер.

...