bcadding非常小的花车给出0

时间:2013-01-31 02:34:44

标签: php floating-point-precision bc

感谢堆栈,我了解了浮点不精确,所以我去了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

1 个答案:

答案 0 :(得分:2)

The / operator返回浮点数或整数。它干扰了您正确使用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

任意精度算术本质上比浮点算术慢。这是您为数十,数百或数千个精度数字支付的价格。