ここから本文です

phpでの誤差の対処で、(1)100をかける、(2)stringにする、で具体的な内...

tuk********さん

2012/3/2811:33:20

phpでの誤差の対処で、(1)100をかける、(2)stringにする、で具体的な内部処理はどうなっているのでしょうか。

以下、見つけた記事からの引用です。

問題の処理(ceilすると、出力が異なる。)
$a=2*10770*1.35;
echo $a; // 29079
echo ceil($a); // 29080

1)
$a = bcmul( 2, bcmul( 10770, 1.35, 2 ), 2 );
echo $a; // 29079.00
echo ceil($a); // 29079

2)
$a= 2 * 10770 * 1.35 * 100;
echo ($a/100); // 29079.00
echo ceil($a/100); // 29079

3)
$a = (string) (2*10770*1.35);
echo $a; // 29079
echo ceil($a); // 29079

最初と2)と3)の質問になります。
$a=2*10770*1.35の二つのecho表示が異なるのはなぜでしょうか。
echo時の処理は、ceilとは異なるのでしょうか。
(それとも、整数値での結果が、echoは有効数字全てを表示すると思うのですが、
小数点以下がないため整数値だと思います。そのため、ceilでなぜ異なるのか
分かりません。)

2)なぜ100をかけると同じになるのでしょうか。
(誤差を少なくするためとは分かるのですが、具体的に、何がどうなって
ござが少なくなっているのでしょうか。100をかけてround等を使えば分かるのですが、
ただ100をかけただけでなぜ誤差が少なくなるのでしょうか。int型にキャストされる
からでしょうか)

3) (string) キャスト後の処理はどうなっているのでしょうか。

よろしければご回答をお待ちしております。

閲覧数:
1,429
回答数:
1

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

shi********さん

編集あり2012/3/2814:10:38

コンピュータの内部表現が2進数なので、2^-n(1/2,1/4.,1/8・・・)の和で表せない小数値を使えば必ず誤差が出ます。人間には0.1や0.01は「割り切れた」数字ですが2進数では無限小数になります。

浮動小数点の1.35は135/100とは一致しません。

下記のようにすればわかります。

<?php
$a = 2 * 10770 * 1.35;
$b = 2 * 10770 * 135 / 100;
if ($a !== $b) { print 'result = ' . ($a - $b); }

∴ 「* 1.35」ではなく、「*135 /100」で計算すれば誤差は出ません。提示された(2)では「1.35*100」が「135」として扱われていると推測されます。

この回答は投票によってベストアンサーに選ばれました!

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる