PHP浮动使用的最佳实践

时间:2013-03-24 16:20:18

标签: php

我已经阅读了Floating-Point guide关于在PHP中使用float类型的内容。答案是使用BC Math扩展。使用字符串可以将float表示为精确类型,并防止浮点和整数问题。

与此同时,我没有在Github上找到任何好的例子,这个网站使用BC数学扩展。什么是强制PHP使用字符串的简洁方法,如何评估它们?

特别是对于使用MySQL DECIMAL数据类型的BC Math扩展的最佳方法是什么?

我的PHP 5.4.10示例测试,正确的答案是:0.2999999999996

<?php
bcscale(13);

$a = '0.3';
$b = '0.0000000000004';

echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.2999999999996
echo '<hr />';

$a = "0.3";
$b = "0.0000000000004";

echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.2999999999996
echo '<hr />';

$a = 0.3;
$b = 0.0000000000004;

echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
echo '<hr />';

$a = '0.3';
$b = '0.0000000000004' + 0;

echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
echo '<hr />';

$a = (string) 0.3;
$b = (string) 0.0000000000004;

echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
echo '<hr />';

$a = strval(0.3);
$b = strval(0.0000000000004);

echo $a-$b; // 0.3
echo '<br />';
echo bcsub($a, $b); // 0.3000000000000
?>

1 个答案:

答案 0 :(得分:4)

最好的方法是不使用BC Math,而是开始使用GMP。看看on benchmark。 GMP比BC Math快30倍。

我使用DECIMAL(12,0)和DECIMAL(27,0)和php开始吮吸apr。在10 ^ 19和更高。演示:

//PHP Version 5.3.10,  FreeBSD 8.2-RELEASE amd64

$a = pow(10, 18);
var_dump($a, $a > ($a - 1), ($a - 1) > $a, ($a - 1) == $a, ($a - 1) === $a);
// int(1000000000000000000)
// bool(true)
// bool(false)
// bool(false)
// bool(false)

$a = pow(10, 19);
var_dump($a, $a > ($a - 1), ($a - 1) > $a, ($a - 1) == $a, ($a - 1) === $a);

// double(1.0E+19)
// bool(false)
// bool(false)
// bool(true)
// bool(true)

我制作了Decimal班,here is simple implementation。稍后你可以实现相同的界面,但使用本机php数学运算或BC数学或任何你想要的。 Yupp,函数调用和对象创建会有开销,但是我们编写其他开发人员可以读取的代码,不是吗?

P.S。 来自PHP Secure Communications的人有自己的实现 - Math_BigInteger,它涵盖了所有潜在需求,但对我的任务来说太沉重了。

更新:,因为PHP 5.6 GMP已实施internal operators overloading,因此gmp资源可用作常规数字(主要是)。