1

金額をセントに変換しようとしていますが、毎回 1 セントずれています。PHP拡張機能を使用せずにこれを行う最良の方法は何ですか?

$amount = 129.95;

$amountInCents = intval(floatval($amount) * 100);

echo $amountInCents; //output: 12994
4

3 に答える 3

4

浮動小数点演算と値の格納が不正確であるため ( http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html )、浮動小数点は 129.95 などの多くの値を正確に表すことができません。この場合、192.95 を正確に格納することはできないため、129.9499999 のようになります。

したがって、intval を使用して切り捨てると、12994.999 であることがわかり、12994 に切り捨てられます。

これを解決するには、試すことができます

1) ドルとセントの金額を のような文字列として取得する場合、"$129.95"文字列解析を使用してドルとセントを整数として計算します。

2) float 値を int に変換する前に 0.00001 のような非常に小さな値を追加します。

3) intval を使用する前にround http://php.net/manual/en/function.round.phpを使用して、最も近い整数に丸めます。

于 2013-06-14T02:53:15.120 に答える
4
$amount = 129.95;
echo (string)(floatval($amount) * 100); // cast it to string
于 2013-06-14T03:00:41.820 に答える
1

すべての数値が浮動小数点で表現できるわけではありません。(たとえば)可能な 64 ビット値は 2 64 個しかないため (エンコーディングでは NaN や無限大などを要求するため、実際の値は少なくなります)、浮動小数点数は無限にあるため、これは明らかです。

詳細については、この回答を参照してください。

したがって、 のような数値は実際129.95には129.949999999923234intval(val * 100)12994

1 つの解決策は、数値を切り捨てるのではなく四捨五入することです。ほとんどの言語では、これを行う方法が多数用意されています。または、次の方法でエミュレートできます。

intval(val * 100 + 0.5);

または、IEEE754 float を使用しないことで問題を回避できます。整数型はおそらく今日では十分に大きいので、これらの種類のエラーが発生しない整数セントを直接格納することができます (計算の複雑さによっては他のエラーが発生する可能性がありますが、浮動小数点に関連するものよりもほぼ確実に少なくなります)点)。

また、より広い範囲が必要な場合は BigInteger タイプのパッケージを選択する必要がある場合があります。

于 2013-06-14T02:59:10.183 に答える