人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

整数値の取扱について

$a = 16.81;
$b = 100;

$result = $a * $b;

echo $result . "<br>";

$result = (int)$result;

echo "int後" . $result;

についてPHPで結果を出したところ、

1681
int後1680

という結果になります。perlでも同様の式を行うと同じ結果になります。

尚、$a = 16.82; の場合は意図した値 ( int後 1682 )になります。

この原因、対処法についてご存知の方はいらっしゃいますでしょうか?

●質問者: kou32rr
●カテゴリ:インターネット ウェブ制作
✍キーワード:echo Perl PHP 対処 意図
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● zzz_1980
●50ポイント ベストアンサー

C言語で double を使ってもそうなりますが、これは

'16.81' を2進の浮動小数点に変換する際の誤差によるものです。

(マイナスの誤差がのって、だいたい1.68099999999999977263e+1になります。)

int への変換は小数点部の切捨てによっておこないますので100倍して小数部を切り捨てると1681にならず1680になってしまいます。

http://www.phppro.jp/phpmanual/php/language.types.float.html#war...

php には任意精度数学関数がありますので、これを利用すれば発生する誤差をコントロールできます。

'16.82'は変換するとプラスの誤差がのって、1.682000000000000028421709430404e+01 になりますので、100倍して切り捨てれば1682となり誤差がないように見えます。


2 ● pahoo
●50ポイント

原因・対策については zzz_1980 さんが回答しているとおりです。

任意精度数学関数について補足します。


PHP4 以降では、--enable-bcmath を付けてコンパイルされている場合に、BCMath任意精度数学関数が利用できるようになります。

これを使い、下記のようにすることで問題は解決します。

<?php
$a = 16.81;
$b = 100;

//普通の乗算
$result = $a * $b;
echo "普通の乗算 = " . $result . "<br />\n";
$result = (int)$result;
echo "int後 = " . $result . "<br />\n";

//BCMathによる乗算
$result = bcmul($a, $b);
echo "BCMathによる乗算 = " . $result . "<br />\n";
$result = (int)$result;
echo "int後" . $result . "<br />";
?>
関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ