我试图让浮点数(18,16)向右填充零,但这不起作用,因为它总是以 1 而不是零结尾。我的猜测是因为我指定错误但我不确定如何正确执行。
示例:
12.12234
必须成为12.122340000000000
并且1.01
必须成为1.01000000000000
。
为了实现这一点,我正在使用sprintf('%18.016f', $fMyFloat);
,但这总是以 1 而不是 0 结尾。显然我正在监督一些事情,我只是不知道是什么。任何帮助是极大的赞赏。
此测试代码:
$data = array(
12.12234,
1.01
);
foreach($data as $fMyFloat){
echo sprintf('%18.016f', $fMyFloat) . PHP_EOL;
}
...在我的 64 位计算机上打印:
12.1223399999999994
1.0100000000000000
您面临着众所周知的浮点精度问题。将整数从基数 10 转换为基数 2 非常简单(且精确),但基数为 10 的浮点数并不总是以 2 为基数精确表示。此问题并非特定于 PHP,但PHP 手册中有一个警告:
浮点数的精度有限。尽管取决于系统,但 PHP 通常使用 IEEE 754 双精度格式,由于在 1.11e-16 的数量级四舍五入,这将给出最大的相对误差。非初等算术运算可能会产生更大的误差,当然,当多个运算复合时,必须考虑误差传播。
此外,可以精确表示为以 10 为底的浮点数的有理数,如 0.1 或 0.7,没有精确表示为以 2 为底的浮点数,无论尾数大小如何,它都在内部使用。因此,它们不能被转换成它们的内部二进制对应物,而不会损失很小的精度
实现这种精度的唯一机会是将数字作为字符串来操作。PHP 捆绑了两个任意精度库,可以在您需要匹配字符串时为您提供帮助:GNU Multiple Precision和BC Math。这是 bcmath 的一个小技巧:
$data = array(
'12.12234',
'1.01'
);
bcscale(16);
foreach($data as $fMyFloat){
echo bcdiv($fMyFloat, 1) . PHP_EOL;
}
但是,在这种情况下,您可能可以使用简单的字符串函数:
$data = array(
'12.12234',
'1.01'
);
foreach($data as $fMyFloat){
list($a, $b) = explode('.', $fMyFloat);
echo $a . '.' . str_pad($b, 16, 0) . PHP_EOL;
}