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

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

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

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

Q&A

解決済

7回答

26651閲覧

PHPで小数点第3位以下を切り捨てたい。

coffee

総合スコア139

PHP

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

0グッド

0クリップ

投稿2015/06/11 08:32

やりたい事は下記のような事です。

1.450 -> 1.45
1.455 -> 1.45
1.459 -> 1.45

この様に小数点第3位以下を四捨五入等せずに切り捨てたいです。

そこで、round関数を使って下記のように書いてみましたが、
勝手に小数点第3位が四捨五入されました。。

lang

1round(1.459, 2, PHP_ROUND_HALF_DOWN); 2-> 1.46

マニュアルを見ると、第三引数の modePHP_ROUND_HALF_DOWN を指定すれば、
うまくいくと思ったのですが、、何かいい方法あれば教えて下さい。

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

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

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

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

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

guest

回答7

0

回答は既に出ていますが、roundはそもそも広義の「四捨五入」の関数です。
表現がめんどくさいので整数に丸める前提で説明します。
丸める部分がちょうど 0.5 (HALF)の時に、狭義の四捨五入だと切り上げますが、そうじゃない方法が他に3通りあると言うことです。
その1つである PHP_ROUND_HALF_DOWN は、0.5よりちょっとでも大きいと切り上げるが、0.5以下ときは切り捨てるということです。Wikipediaの「端数処理」の項目では、「五捨五超入」と書かれています。

正確には、PHP_ROUND_HALF_UP以外は四捨五入じゃ無いので、関数の説明に四捨五入と書けず、「まるめ」と表現したのでしょう。しかし、切り捨て、切り上げも「まるめ」の一種なので、その点でおかしくなっています。

追記:
floor()やceil()に何故桁数指定機能が無いのかを考えてみると、単純に100をかけて切り捨てて100で割る方法だと、値によっては、10進数に直してから第3位を切り捨てるのと比べると差が出るケースもあったりするので、避けてるのかなと言う気がします。いったん10進数に変換してから(つまり文字列に変換してから)処理した方が正確だと思います。

実際、試してみると差が出るケースがありました。
PHP 5.3.3 (cli) (built: Oct 30 2014 20:12:53)

lang

1<?php 2$a=10+0.001*40; 3var_dump($a); //=> float(10.04) 4var_dump(floor($a*100)/100); //=> float(10.03)

いったん文字列に直して、小数点以下3桁目以降を削除するという方法がいいようです。

lang

1var_dump(floor($a)+substr(sprintf("%5.3f",$a-floor($a)),0,4));

とか。$aが負の場合も考慮すると、正負の場合分けが必要そうです。

投稿2015/06/11 13:42

編集2015/06/11 15:33
otn

総合スコア84555

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

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

0

lang

1$arg = 1.459; 2echo (floor($arg * 100)) / 100;

これでどうでしょう。

投稿2015/06/11 08:42

orange0190

総合スコア1698

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

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

0

ベストアンサー

だいぶ日が経っていますが、私のやり方も参考になればと思います。
私も小数の演算に関しては痛い目に遭いました。。

こんな感じです。sprintfは不要かもですが、適当ですみません。

ceil(sprintf("%.3f", 1.459) + 0.001)*100)/100)-0.01

ceilは「.0なら切り上げない」「.1以上なら切り上げる」性質を持っていますので、
これを利用します。
強制的に+0.001してからceilをかませ、最後に繰り上がった分を強制的に引く(-0.01)わけです。

元が1.459の場合・・・ceil(1.46 *100)/100なので結果は変わらず。最後に-0.01で1.45です。
元が1.455の場合・・・ceil(1.456 *100)/100なので0.006が0.01に繰り上がります。最後に-0.01で1.45です。

何かと不安要素の多いfloorを使うよりも、ceilはハッキリしているので確実な方法だと思っています。

輸出入のWebシステムで実際に動いています。
納品書などに重量や単価、横計など上記の数式を用いて、PHPExcelで紙を出しています。

為替やkg⇔ポンドの変換等で多用していますが、差分が出たことはありません。

解決済とは思いますが、せっかくなのでご参考まで。

投稿2015/11/07 03:59

Shiroyama

総合スコア15

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

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

0

単純な方法ですが、下記のような方法を使えば簡単にできるような気もするのですが・・・・。

<?php $data = 1.4499999; if(is_float($data)){ $tmp = explode(".", $$data); $data = $tmp[0].".".substr($tmp[1], 0, 2); } var_dump($data); exit; ?>

投稿2015/06/11 14:50

編集2015/06/11 15:53
takayukiinaba

総合スコア1158

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

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

otn

2015/06/11 15:44

いろいろ考えて追記している間に、文字列を使った回答も出ましたね。 なるほど、takayukiinaba さんの方法だと、正負の場合分けは要らなそうです。 と思ったけど、$data = 5; とかだと$tmp[1]で警告が出ますね。やはり場合分けは必要か。 と思ったけど、$tmp = explode(".", $data.".0"); で回避できます。 最後は文字列のままなので、数値化のために0を足すのでしょうか。
takayukiinaba

2015/06/11 15:52

otn さん 突っ込みありがとう御座います。 確かにそうですね、入力されるデータが実数値という認識でした。
guest

0

PHPはあまり詳しくないですけど…

四捨五入されてしまうのであれば
"0.05"を引いてみてはいかがでしょう?

round(1.459, 2, PHP_ROUND_HALF_DOWN);
-> 1.46
round(1.459 - 0.05, 2, PHP_ROUND_HALF_DOWN); // round(1.454, 2, PHP_ROUND_HALF_DOWN);
-> 1.45

切り上げ、切り捨て、四捨五入の調整によくあるアルゴリズムです

投稿2015/06/11 08:44

kutsulog

総合スコア985

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

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

0

せっかくなので、別のアプローチとして
文字列で切り出すのはどうですか?
小数点第3位以下切り捨てであれば

preg_match("/([0-9]+.[0-9]{2})/",$val,$tmp);

$result = $tmp[1];

で取れそうな気がします。

投稿2015/06/24 15:03

cocacola5959

総合スコア32

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

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

0

float a = 123.456
int ans = (a * 1000);
flat a = ans;
print( a );

ですかね。

投稿2015/06/11 09:29

MasaakiIrie

総合スコア1021

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問