質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

4回答

5968閲覧

MYSQLで、SELECTで掛け算を行った時に大量な小数点以下も表示されてしまうのを直したい

sanset

総合スコア186

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2017/06/21 06:04

MYSQLで、以下のようなテーブルを作成しました。

table名 result

|user(varchar)|point(float)|bonus(float)|
|:--|:--|
|tanaka|1|1.1|

ユーザーの持ち点に対して、ボーナスの倍率を掛けるといった簡単な処理で、以下のようなクエリを実行すると、

SQL

1SELECT user, (point * bonus) as get_point FROM result

これのget_pointには、

「1.100000023841858」といった結果で帰ってきます。

結果は単純に電卓で弾いた時のように「1.1」と返ってきてほしいのですが、何故このような結果になってしまうのでしょうか。

単純な内容かもしれませんが、どなたかご教示お願いいたします。

※roundなどで切り上げれば問題ない、といった回答ではなく、どうして電卓と計算が一致しないのかを教えて頂けると助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

MySQLのfloatはIEEE 754に則った浮動小数点数ですが、これは1.1を正確に表現できません

というのも、小数点以下も2進法で格納していますが、10進法の0.1は2進法にすると0.00110011…と無限に続いてしまうので、どこかで打ち切って誤差含みにするしかなくなるのです。

なお、MySQLにはDECIMAL型があって、これは小数点以下も10進法で処理するので、FLOATのような誤差は出ません。

投稿2017/06/21 06:20

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2017/06/21 06:33

回答ありがとうございます! 浮動小数点数の仕様だったのですね。 詳しい解説も頂き感謝です。
guest

0

浮動小数点数は実数を正確に表すことができず、誤差を伴うためです。

浮動小数点数型と誤差

誤算が許されないのであれば、floatではなく固定小数点数型であるdecimalを使用してください。

11.2.2 固定小数点型 (真数値) - DECIMAL、NUMERIC

投稿2017/06/21 06:23

SVC34

総合スコア1149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2017/06/21 06:33

回答ありがとうございます! 浮動小数点数の理解が深まりました。 リンクもありがとうございます。目を通しておきます。
guest

0

どうして電卓と計算が一致しないのか

浮動小数点処理とはそういうものだからとしか言いようがないですね
「1.1」はコンピュータは「1.100000023841858・・・」として持っているわけです
その近似値を利用しているに過ぎません。

ためしに以下を確認してみてください

SQL

1create table result(user varchar(30),point float(17,15),bonus float(17,15)); 2insert into result values('tanaka',1,1.1),('suzuki',1.2345,2.3456); 3select * from result;

なので、もう少し精度を低くして計算をすればよいでしょう
たとえば

SQL

1create table result(user varchar(30),point float(17,4),bonus float(17,4)); 2insert into result values('tanaka',1,1.1),('suzuki',1.2345,2.3456); 3select user, (point * bonus) as get_point from result;

投稿2017/06/21 06:41

yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2017/06/28 06:54

返信遅れて申し訳ありません、回答ありがとうございます! 処理の都合上、切り捨ては行いたくなかったのでDECIMAL型を利用することで解決しました。
guest

0

truncateを使います。

投稿2017/06/21 06:13

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2017/06/21 06:31

回答ありがとうございます! 申し訳ありません、数値を丸めたい訳ではなくて、電卓計算のように1×1.1=1.1とならないのは何故ですか?という内容の質問でした。 分かりにくくてご迷惑おかけしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問