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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

1367閲覧

PHP のfloat型判定について?

hatanaka_

総合スコア21

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/04/04 13:57

お世話になります。

phpにはあまり詳しくないのですが、
プログラムを書いていて困った自体に出くわしました。

以下、数値の切り上げ切捨てを設定した値で行う関数を作りましたが、
同じ値のfloat型の変数を比較しているのですが、違う値だといわれてしまいます。
あまりいい書き方でないかもしれませんが、
詳しい方がいたらお願いします。

簡単な処理だと思い、decimalクラスのようなものは使っていません。

$avgは対象値
$threshold閾値です。

php

1 function customRoundUpDown($avg, $threshold) { 2echo "<br>$threshold... $avg"; 3 $syo = $avg > 0 ? floor($avg) : ceil($avg); 4 $joyo = $avg - $syo; 5 $th = floatval($threshold); 6echo " $joyo > ? "; 7echo "\n dump\n"; 8var_dump( $joyo , $th ); 9echo " $joyo === $th を比較" ; 10var_dump($joyo == $th); 11 if ( $joyo >= $th ) { 12echo " ON! "; 13 return $syo + 1; 14 } 15echo " OFF..."; 16 return $syo; 17 }

この実行を行った際の、標準出力が以下です。

<br>0.4... 2.4 0.4 > ? dump float(0.4) float(0.4) 0.4 === 0.4 を比較bool(false) OFF...float(2)

最後のfloat(2)は呼び出し元でのdumpです。

※事象が起こっているのは
php5.4,
centos6.9環境です。
他の環境では試していません。

宜しくお願いいたします。

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

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

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

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

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

guest

回答3

0

コンピュータは内部敵に数値を二進数に変換して保持するので、実数は一定の条件を見たさない限り正確に表現できません。
確実な比較には、おやりになった様に何倍かして整数にして比較するなどの処理が必要です。各種ライブラリも内部で基本的に同じことをやっている筈です。これは言語に依らずついて回る制約です。

投稿2018/04/04 14:14

KojiDoi

総合スコア13671

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

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

hatanaka_

2018/04/04 14:27

ご回答ありがとうございます。現象は知っています。ただ、dumpの値が異なるというのがショックです。何のためのdumpなのか。。。
guest

0

ベストアンサー

浮動小数点数にまつわるよくある誤差のはなしですね。
10進数の0.4というのは2進数では循環小数になってしまい、表示上では同じ0.4 でも、2進数上では違ってしまう、というはなしです。
「浮動小数点 誤差」でぐぐればそこらへんの解説が出てきますんで読んでみてください

投稿2018/04/04 14:11

y_waiwai

総合スコア87749

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

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

hatanaka_

2018/04/04 14:27

ご回答ありがとうございます。現象は知っています。ただ、dumpの値が異なるというのがショックです。何のためのdumpなのか。。。
y_waiwai

2018/04/04 14:33

PHPのことはちとよーわかりませんが、 > $joyo = $avg - $syo; これは小数点どおしの引き算になるんでしょうか。 こういう計算が一番やばい、というか、意図しない結果が出る原因となりますね。 こういう事が起こるのを嫌うなら、たとえば小数点以下2位であれば、各数値を100倍して、整数として計算、比較することですね。
guest

0

失礼しました。。。。

100倍してintに変換したところ、
片方の変数が39と出ました。

という事で、やはり計算にはdecimalなどを利用しろという事ですね。。。

ただ、dumpを吐いて0.4という値で出てくると思っていなかったので、ショックです。。。

この点の説明などあれば、教えて頂ければと思います。お願いします。

投稿2018/04/04 14:05

hatanaka_

総合スコア21

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

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

otn

2018/04/05 05:00

var_dumpのリファレンスのサンプルに、 > float(3.1) という例があるので明らかです。正確に 3.1 というfloat値はあり得ないので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問