LoginSignup
0
0

More than 1 year has passed since last update.

MySQL 小数値だからといって、気軽にFLOAT型を使うと痛い目を見る

Last updated at Posted at 2021-06-18

小数型を扱うときは気にしたほうがいい

面積を扱う機会があり、「mysql 小数」でググって出てきた記事をうのみにして実装したところ、以下のような現象が発生しました。

CREATE TABLE DATA (ID INT, MENSEKI FLOAT);
INSERT INTO DATA (ID, MENSEKI) VALUES (1, 2.1);
SELECT COUNT(*) FROM DATA WHERE MENSEKI >= 2.1;
--1件該当
SELECT COUNT(*) FROM DATA WHERE MENSEKI >= 2.1 AND MENSEKI <= 2.1;
--NOT FOUND !?
SELECT COUNT(*) FROM DATA WHERE MENSEKI <= 2.1;
--NOT FOUND !?

ただし、あらゆるレコードで発生するのではなく、小数点以下がゼロでないレコードでこの現象が発生します。

これは、以下のSQLを実行するとわかります。

SELECT MENSEKI + 0 FROM DATA;
--2.0999999046325684

要は、INSERTされた値は、SELECTで与えているリテラル値と違うんですね。
これは、FLOAT型が IEEE754単精度浮動小数点数 で格納されているためです。

解決策

  • DECIMAL(10,2) 型を利用したら、期待通り動作した
  • FLOAT(10,2) と桁を指定したら期待通り動作した
  • DOUBLE を利用したら期待通り動作した

追記

@reta さんコメントありがとうございます。
基本的に理由がなければ DECIMAL を利用すべきとご意見いただきました。
面積程度の値なら、浮動小数点を使う必要ないということだと思いました。

まとめ

構築時にユースケースになくても、こういう単体テストはちゃんとやったほうがいい。
やらないと「バグ」って言われます・・・・

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0