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

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

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

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

Q&A

解決済

5回答

2390閲覧

【PHP】printf()関数の小数点以下の扱い方について

blueletter5

総合スコア24

PHP

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

0グッド

0クリップ

投稿2021/05/24 04:11

編集2021/05/24 04:13

printf()関数で以下のような記述をしました。

関数の引数を計算すると単純で 5 × (1 - 0.35) で結果は 3.25 となります。
これを$%.1f によって出力するため小数点以下は1桁です。
桁数を指定した場合、指定し桁数以下は「四捨五入」されると思っていました。
よって、自分では Price: 3.3 と出力されると考えていましたが
実際には Price: 3.2 と表示されます。

ちなみに 3.25 を round() 関数で使うと 3.3 と返ってきます。

printf()関数で小数点以下の桁数をしてした場合、四捨五入、切り上げ、切り捨て
いずれでもない値が返ってくるのでしょうか?

このような小数点以下の桁数を扱う方法はPHPの他の関数でも使われるのでしょうか?
この方法の呼称というか名称というのはあるのでしょうか?

初学者です。分かりやすく教えていただければ幸いです。
よろしくお願いいたします。!

<表示結果>
Price: $3.2

3.3

<?php $price = 5; $off = 0.35; printf("Price: $%.1f", $price * (1 - $off)); echo "<br>\n"; echo "<br>\n"; echo round(3.25, 1); ?>

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

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

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

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

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

guest

回答5

0

PHP: printf - Manual

ここには%fのPrecisionについてこう書かれています。

小数点の後に表示する桁数 (デフォルトでは、この値は6です)

丸めるとは書かれていませんね。

投稿2021/05/24 04:18

itagagaki

総合スコア8402

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

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

0

浮動小数点は調整しますが、0.25や0.75など割り切れる数は銀行丸めするみたいですね

PHP

1foreach([3.05,3.15,3.25,3.35,3.45,3.55,3.65,3.75,3.85,3.95] as $val){ 2 print number_format($val,30)."→".sprintf("%.1f<br>",$val); 3}

投稿2021/05/24 05:06

yambejp

総合スコア116720

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

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

yambejp

2021/05/24 05:25

ごく小さい数を足すと四捨五入になります foreach([3.05,3.15,3.25,3.35,3.45,3.55,3.65,3.75,3.85,3.95] as $val){ $val+=(0.1**15);//0.1の15乗 print number_format($val,30)."→".sprintf("%.1f<br>",$val); }
guest

0

誤った形で自己解決しています。出版社も間違っています。

目くじら立てるような話ではないのですが、将来このサイトに到達した人のために書いておきます。

引用テキスト上記の解説ではどうやっても辻褄が合わないので出版社に直接問い合わせようと思いサイトをみてそのテキストのページを観ると正誤表が載っていました。」

とありますが、それも踏まえて出版社のミスです。
先日出版社にも指摘し、誤りである事は確認済みになります。

偶数丸め処理ではありません。浮動小数点の精度による問題です。

PHP初級に求めるようなレベルの問題ではないので、ここで多くを語っても仕方がないのですが、より理解がしたいのであれば浮動小数点とは何か?を調べてみてください。(参考リンクも参考にしてみてください)

概要だけ以下に記載しておきます。
浮動小数点では0.1や0.7も厳密には表現出来ない数字です。
よって例えば3.35に見えてるfloatが3.349999....なのか3.3500...1...なのかによって3.3か3.4どちらに成るかは保証されていないという事になります。

参考リンク:

投稿2022/06/27 04:36

taclose

総合スコア8

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

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

0

自己解決

この記述のある書籍の出版社へ問い合わせをしようと考え出版社のこの書籍のページを見ると
正誤表が出ていました。


誤記のためにご迷惑をおかけし、誠に申し訳ございません。

[誤]
その際、小数点以下で指定された桁数以下の値が5より大きい(この例では3.25より大きい3.251や3.250001など)場合は切り上げ、5以下(この例では3.25以下)は切り捨てになります。よって、表示結果は「Price:$3.2」となります。(B)
[正]
その際、小数点以下で指定された桁数以下の端数は偶数丸め処理が行われ、結果が偶数に近い値へと処理されます。今回のケースでは3.25を丸め処理しているため、偶数に近い値に処理され3.2という値になります。よって、表示結果は「Price:$3.2」となります。

投稿2021/06/01 07:21

blueletter5

総合スコア24

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

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

yambejp

2021/06/01 07:40

私の書いたとおりですね(銀行丸め=偶数丸め) ちなみに古いバージョンのPHPだと3.25が3.3になるものもあります
blueletter5

2021/06/01 14:34

ありがとうございます。 上記の解説ではどうやっても辻褄が合わないので出版社に直接問い合わせようと思いサイトをみてそのテキストのページを観ると正誤表が載っていました。Amazonで購入したのですが、まさか出版社のウェブサイトに正誤表が載っているなどと思ってもいませんでした。何にしろホッとしました。
guest

0

roundだと、丸め方を指定できます。
PHP: round - Manual

printfでの丸めだと、やってみるとPHP_ROUND_HALF_EVENになるっぽいですね。

ただ、リファレンスにはその旨が書かれてないので、いずれにせよroundを使って自分で好みの丸め方を指定するのが良いでしょうね。

これと別に、浮動小数点数の誤差の話があります。
0.25だと浮動小数点数で正確に表せますが、0.35は2の冪乗の和じゃないので正確に表せません。
%.1f0.4じゃなくて0.3になりますね。微妙に0.35より小さい数と言うことです。

投稿2021/05/24 11:46

otn

総合スコア85901

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問