yoku0825さん

ご回答ありがとうございます。ktsaです。

こちらの運用上の都合ですが、将来の製品の仕様変更により、
どんな値が入るかわからないということもあるので、
あまり桁指定はしたくないんですよね(^^ゞ
整数部の桁を超えた値は正常に入りませんよね?

mysql> CREATE TABLE t1 (num decimal(32, 20));
Query OK, 0 rows affected

mysql> INSERT INTO t1 VALUES (12345678901234567890.123456);
ERROR 1264 : Out of range value for column 'num' at row 1
mysql>

それとDECIMAL型は最低でも整数部4バイト、小数部4バイトですよね?
FLOATは桁指定しなければ、全部4バイト、有効数値7桁ですね。

本当は浮動小数点型で整数部と小数部を指定するのではなく、
単純に全部含めた有効数値桁数を指定できるといいなぁなどと思っていました。

今まで有難うございました。



2014年6月9日 10:31 yoku ts. <yoku0825@gmail.com>:
こんにちは、yoku0825といいます。

float型の…という件名だったのでfloat型な返信をしましたが、
なんらかの理由でこだわりがあるというわけで *ないのであれば* DECIMAL型の方が良いと思います。


mysql56> CREATE TABLE t1 (num decimal(32, 20));
Query OK, 0 rows affected (0.05 sec)

mysql56> INSERT INTO t1 VALUES (1.2345678901234567890);
Query OK, 1 row affected (0.00 sec)

mysql56> SELECT * FROM t1;
+------------------------+
| num |
+------------------------+
| 1.23456789012345678900 |
+------------------------+
1 row in set (0.00 sec)


こちらの方が、丸め誤差もありませんし。


yoku0825


2014年6月9日 0:38 ktsa5236@gmail.com <ktsa5236@gmail.com>:

yoku0825さん

お返事遅くなりまして、申し訳ございません。

ご回答、有難うございます。
確かに7桁は保存はされているようですね。

yoku0825さんのテーブルでround()関数を使って、もう少し試してみました。

mysql> SELECT num, ROUND(num,5),ROUND(num,6),ROUND(num,7) ,ROUND(num,8) ,ROUND(num,9),ROUND(num,13) from t1;
+--+--+--+--+--+--+--+
| num | ROUND(num,5) | ROUND(num,6) | ROUND(num,7) | ROUND(num,8) | ROUND(num,9) | ROUND(num,13) |
+--+--+--+--+--+--+--+
| 1.23457 | 1.23457 | 1.234568 | 1.2345679 | 1.23456788 | 1.234567881 | 1.2345678806305 |
+--+--+--+--+--+--+--+
1 row in set

アプリ側では、長めの第2引数のround()関数で逃げておけば良さそうですね。

有難うございました。



2014年6月3日 11:10 yoku ts. <yoku0825@gmail.com>:

こんにちは、yoku0825といいます。

内部的にはCのfloatを使っているので、格納はされているけれど丸められているんだと思います。
(↓5.6ですが)

mysql56> CREATE TABLE t1 (num float not null, num_20 float(20, 16));
Query OK, 0 rows affected (0.05 sec)

mysql56> INSERT INTO t1 VALUES (1.2345678901234567890, 1.2345678901234567890);
Query OK, 1 row affected (0.01 sec)

mysql56> SELECT * FROM t1;
+---------+--------------------+
| num | num_20 |
+---------+--------------------+
| 1.23457 | 1.2345678806304932 |
+---------+--------------------+
1 row in set (0.00 sec)

mysql56> SELECT num* 10000, num_20* 10000 FROM t1;
+--------------------+------------------------+
| num* 10000 | num_20* 10000 |
+--------------------+------------------------+
| 12345.678806304932 | 12345.6788063049320000 |
+--------------------+------------------------+
1 row in set (0.00 sec)

掛け算で値が狂うのは、浮動小数点数なのでご愛嬌(?)
表示桁数の制御はこのあたりですかね。。



yoku0825


2014年6月3日 10:38 ktsa5236@gmail.com <ktsa5236@gmail.com>:

いつもお世話になっております。ktsaと申します。
表題の件について教えていただきたいのですが、
MySQLのfloat型は、IEEE754に則っているのでしょうか?
7桁ではなく、常に有効数字6桁までしか保存されないように思います。
環境とテスト内容ですが、
MySQL5.0.22-community-nt
データベースはInnoDB

CREATE TABLE `testtb` (
`A` tinyint(4) NOT NULL default '0',
`B_dbl` double default NULL,
`C_float` float default NULL,
PRIMARY KEY (`A`)
) ENGINE=InnoDB DEFAULT CHARSET=sjis;

Insert into testtb values(11,1.2345678901234567890,1.2345678901234567890);

を実行する。

コンソール実行画面結果は、

mysql> Insert into testtb values(11,1.2345678901234567890,1.2345678901234567890);
Query OK, 1 row affected

mysql> select * from testtb where A=11;
+----+------------------+---------+
| A | B_dbl | C_float |
+----+------------------+---------+
| 11 | 1.23456789012346 | 1.23457 |
+----+------------------+---------+
1 row in set

とC_float列は7桁目が丸めまれ常に有効数字が6桁になります。
他の値でも試しましたが同様でした。

よろしくお願いいたします。