web-dev-qa-db-ja.com

MySQL浮動小数点比較の問題

MySQLデータベーススキーマに浮動小数点列を導入することで、浮動小数点値の比較が常に正しい結果を返すとは限らないという問題が発生しました。

1-50.12
2-34.57
3-12.75
4 -...(残りはすべて12.00未満)

SELECT COUNT(*) FROM `users` WHERE `points` > "12.75"

これで「3」が返されます。

MySQLでの浮動小数点値の比較は悪い考えであり、10進型がより良いオプションであることを読みました。

フロートタイプを進めて、比較が正しく機能するようになることを期待していますか?

21
Sharief Shaik

以下の問題に気づきましたか?

CREATE TABLE a (num float);

INSERT INTO a VALUES (50.12);
INSERT INTO a VALUES (34.57);
INSERT INTO a VALUES (12.75);
INSERT INTO a VALUES (11.22);
INSERT INTO a VALUES (10.46);
INSERT INTO a VALUES (9.35);
INSERT INTO a VALUES (8.55);
INSERT INTO a VALUES (7.23);
INSERT INTO a VALUES (6.53);
INSERT INTO a VALUES (5.15);
INSERT INTO a VALUES (4.01);

SELECT SUM(num) FROM a;
+-----------------+
| SUM(num)        |
+-----------------+
| 159.94000005722 | 
+-----------------+

それらの行のいくつかの間に余分な0.00000005722スプレッドがあります。したがって、これらの値の一部は、初期化された値と比較するとfalseを返します。

浮動小数点演算と比較の問題を回避するには、DECIMALデータ型を使用する必要があります。

ALTER TABLE a MODIFY num DECIMAL(6,2);

SELECT SUM(num) FROM a;
+----------+
| SUM(num) |
+----------+
|   159.94 | 
+----------+
1 row in set (0.00 sec)
26
Daniel Vassallo

私は一度同じような問題に直面しました。 'float'フィールドを 'decimal'に変換します。それは間違いなく問題を解決します。

2
intellidiot

私はこれをします

WHERE abs(value - 12.75)<0.001

しかし、私は同意します。どの言語でも浮動小数点の等式を比較でき、保存された値が挿入した正確な数値と等しい場合、問題はないはずです。

小数点以下2桁と完全に一致する値しかないため、精度エラーはMySQLでのこのような不一致の明らかな理由のようには聞こえません。

2
ninja

浮動小数点なので、何が問題なのでしょうか。 3は正しい結果である可能性がありますが、データベースが12.75について何を考えているかによって異なります。 12.75ですか、それとももう少しですか?

正確な数値が必要な場合は、DECIMALを使用してください。

1
Frank Heikens

フロートの同等性の比較には問題があります。これにより、予期しない結果が生じる可能性があります。これは、浮動小数点演算の内部実装によるものです。

1
Andrey

数字と文字列を比較しますか?

0
dkretz

FLOATまたはDECIMALの代わりにREALを使用します。

0
Anil Dhandar