teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2015/06/11 15:33

投稿

otn
otn

スコア86349

answer CHANGED
@@ -3,4 +3,21 @@
3
3
  丸める部分がちょうど 0.5 (HALF)の時に、狭義の四捨五入だと切り上げますが、そうじゃない方法が他に3通りあると言うことです。
4
4
  その1つである PHP_ROUND_HALF_DOWN は、0.5よりちょっとでも大きいと切り上げるが、0.5以下ときは切り捨てるということです。Wikipediaの「端数処理」の項目では、「五捨五超入」と書かれています。
5
5
 
6
- 正確には、PHP_ROUND_HALF_UP以外は四捨五入じゃ無いので、関数の説明に四捨五入と書けず、「まるめ」と表現したのでしょう。しかし、切り捨て、切り上げも「まるめ」の一種なので、その点でおかしくなっています。
6
+ 正確には、PHP_ROUND_HALF_UP以外は四捨五入じゃ無いので、関数の説明に四捨五入と書けず、「まるめ」と表現したのでしょう。しかし、切り捨て、切り上げも「まるめ」の一種なので、その点でおかしくなっています。
7
+
8
+ 追記:
9
+ floor()やceil()に何故桁数指定機能が無いのかを考えてみると、単純に100をかけて切り捨てて100で割る方法だと、値によっては、10進数に直してから第3位を切り捨てるのと比べると差が出るケースもあったりするので、避けてるのかなと言う気がします。いったん10進数に変換してから(つまり文字列に変換してから)処理した方が正確だと思います。
10
+
11
+ 実際、試してみると差が出るケースがありました。
12
+ PHP 5.3.3 (cli) (built: Oct 30 2014 20:12:53)
13
+ ```lang-PHP
14
+ <?php
15
+ $a=10+0.001*40;
16
+ var_dump($a); //=> float(10.04)
17
+ var_dump(floor($a*100)/100); //=> float(10.03)
18
+ ```
19
+ いったん文字列に直して、小数点以下3桁目以降を削除するという方法がいいようです。
20
+ ```lang-PHP
21
+ var_dump(floor($a)+substr(sprintf("%5.3f",$a-floor($a)),0,4));
22
+ ```
23
+ とか。$aが負の場合も考慮すると、正負の場合分けが必要そうです。