我可以依靠PHP php.ini精度解决方法来解决浮点问题吗
我发现了PHP中浮点问题的一些解决方法:
php.ini设置 precision = 14
342349.23 - 341765.07 = 584.15999999992 // floating point problem
假设是php.ini设置 precision = 8
342349.23 - 341765.07 = 584.16 // voila!
那有多糟?
- 请注意,我不能使用整数计算(float * 100 =美分),这样做太迟了。
- 我不会处理高于10 ^ 6的数字
- 我不需要比较数字
更新
@Baba答案是好的,但他用precision=20
,precision=6
在他的测试…所以还是我不知道是不是要去工作与否。
请考虑以下几点:
可以说precision = 8
,我唯一要做的就是加法+
和减法-
A + B = C
A - B = C
对于0..999999.99之间的数字(其中A和B是带小数位的数字),精度解决方法会失败吗?如果是这样,请提供一个例子。
简单的测试就可以完成工作:
// if it fails what if I use 9,10,11 ???// **how to find when it fails??? **
ini_set('precision', 8);
for($a=0;$a<999999.99;$a+=0.01) {
for($b=0;$b<999999.99;$b+=0.01) {
// mind I don't need to test comparision (round($a-$b,2) == ($a-$b))
echo ($a + $b).','.($a - $b)." vs ";
echo round($a + $b, 2).','.round($a - $b, 2)."\n";
}
}
但显然工作量99999999 * 2
太大,所以我无法运行此测试
当精度解决方法失败时,如何估算/计算?没有如此疯狂的考验? 如何计算是否会失败?
*我不需要知道浮点数的计算方法,但是如果您知道精度以及A和B的范围,但在解决方法失败时
请记住, 美分和bcmath是最好的解决方案。但是我仍然不确定解决方法是否会因减法和加法而失败或失败
回答:
介绍
浮点算术被许多人视为深奥的话题。这是相当令人惊讶的,因为浮点数在计算机系统中无处不在。大多数小数没有精确表示为二进制分数,因此会进行一些舍入。一个好的开始是每位计算机科学家都应该了解的浮点运算法则
回答:
问题1
如果我只需要 (货币),我可以依靠此解决方案吗?
答案1
如果您需要 那么答案是 即使您一直使用php精度设置也无法始终确定 小数not going towork on numbers higher than 10^6
。
在计算过程中,如果长度小于8,则可能会增加精度长度
问题2
如果不能,当此解决方案失败时,您能否提供清晰的示例?
答案2
ini_set('precision', 8); // your precision$a = 5.88 ; // cost of 1kg
$q = 2.49 ;// User buys 2.49 kg
$b = $a * 0.01 ; // 10% Discount only on first kg ;
echo ($a * $q) - $b;
输出量
14.5824 <---- not precise 2 digits calculations even if precision is 8
问题3
哪个php.ini.precision值最适合两位数字和金钱计算?
答案3
精度和金钱计算是两件不同的事情…使用PHP精度作为财务计算或浮点长度的基础不是一个好主意
回答:
为了避免运行一些例子使用起来bcmath
,number_format
并简单minus
$a = 342349.23;$b = 341765.07;
ini_set('precision', 20); // set to 20 echo $a - $b, PHP_EOL;
echo floatval(round($a - $b, 2)), PHP_EOL;
echo number_format($a - $b, 2), PHP_EOL;
echo bcsub($a, $b, 2), PHP_EOL;
输出量
584.15999999997438863584.15999999999996817 <----- Round having a party
584.16
584.15 <-------- here is 15 because precision value is 20
ini_set('precision', 14); // change to 14 echo $a - $b, PHP_EOL;
echo floatval(round($a - $b, 2)), PHP_EOL;
echo number_format($a - $b, 2), PHP_EOL;
echo bcsub($a, $b, 2), PHP_EOL;
输出量
584.15999999997584.16
584.16
584.16 <-------- at 14 it changed to 16
ini_set('precision', 6); // change to 6 echo $a - $b, PHP_EOL;
echo floatval(round($a - $b, 2)), PHP_EOL;
echo number_format($a - $b, 2), PHP_EOL;
echo bcsub($a, $b, 2), PHP_EOL;
输出量
584.16584.16
584.16
584.00 <--- at 6 it changed to 00
ini_set('precision', 3); // change to 3echo $a - $b, PHP_EOL;
echo floatval(round($a - $b, 2)), PHP_EOL;
echo number_format($a - $b, 2), PHP_EOL;
echo bcsub($a, $b, 2), PHP_EOL;
输出量
584584
584.16 <-------------------------------- They only consistent value
0.00 <--- at 3 .. everything is gone
回答:
忘掉浮点数,cents
然后算入,然后除以100
是否太晚,只要简单地使用number_format
它就对我来说是一致的。
更新资料
问题1:对于0..999999.99之间的数字(其中A和B是带小数位的数字),精度解决方法会失败吗?如果是这样,请提供一个例子
0
以999999.99
递增的形式0.01
大约99,999,999
是循环的组合可能性,9,999,999,800,000,000
我真的不认为有人愿意为您运行这种测试。
由于浮点数是具有有限精度的二进制数,因此尝试设置precision
它对确保精度的作用有限。这是一个简单的测试:
ini_set('precision', 8);$a = 0.19;
$b = 0.16;
$c = 0.01;
$d = 0.01;
$e = 0.01;
$f = 0.01;
$g = 0.01;
$h = $a + $b + $c + $d + $e + $f + $g;
echo "Total: " , $h , PHP_EOL;
$i = $h-$a;
$i = $i-$b;
$i = $i-$c;
$i = $i-$d;
$i = $i-$e;
$i = $i-$f;
$i = $i-$g;
echo $i , PHP_EOL;
输出量
Total: 0.41.0408341E-17 <--- am sure you would expect 0.00 here ;
尝试
echo round($i,2) , PHP_EOL;echo number_format($i,2) , PHP_EOL;
输出量
00.00 <------ still confirms number_format is most accurate to maintain 2 digit
以上是 我可以依靠PHP php.ini精度解决方法来解决浮点问题吗 的全部内容, 来源链接: utcz.com/qa/422383.html