0

スタックのおかげで、浮動小数点の不正確さについて学んだので、bc 関数に行きました。

10^-10これは「通常の」フロートではうまく機能しますが、タイプなどの非常に小さなフロートではbcadd常に0.

これらの小さなフロートを正確に追加するために私が間違っていることを誰かに教えてもらえますか?

よろしくお願いします!


PHP

$numerator = 1;
$denominator = 1000000000;
$quotientOne = $numerator / $denominator;

$numerator = 1;
$denominator = 1000000000000000;
$quotientTwo = $numerator / $denominator;

$smallSum = bcadd($quotientOne, $quotientTwo, 100);

echo $quotientOne . "<br>";
echo $quotientTwo . "<br>";
echo $smallSum . "<br>";

与える

1.0E-9
1.0E-15
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
4

1 に答える 1

3

この/演算子は、浮動小数点または整数のいずれかを返します。bcadd() を正しく使用しようとする試みを妨げています。bcadd() がその内容を表示する機会を得る前に、浮動小数点演算の制限が定着します。

echo gettype($numerator / $denominator);
double

bcdiv()代わりに使用してください。bc*() 関数は引数として文字列を取り、文字列も返すことに注意してください。

$ cat code/php/test.php
<?php
$num_1 = 1;
$denom_1 = 1000000000;

# Cast values to string type to be crystal clear about what you're doing.
$q_1 = bcdiv((string)$num_1, (string)$denom_1, strlen($denom_1));
printf("q_1: %s\n", $q_1);

$num_2 = 1;
$denom_2 = 1000000000000000;

# php will do an implicit conversion to string anyway, though.
$q_2 = bcdiv($num_2, $denom_2, strlen($denom_2));
printf("q_2: %s\n", $q_2);

printf("sum: %s\n", bcadd($q_1, $q_2, strlen($denom_2)));
?>

$ php code/php/test.php
q_1: 0.0000000010
q_2: 0.0000000000000010
sum: 0.0000000010000010

任意精度の演算は、本質的に浮動小数点演算よりも低速です。これは、数十、数百、または数千桁の精度に対して支払う代償です。

于 2013-01-31T03:01:57.670 に答える