我可以依赖PHP php.ini精确解决方法为浮点问题

我发现一些解决方法floating point problemPHP

PHP.ini设置精度= 14

342349.23 - 341765.07 = 584.15999999992 // floating point problem

PHP.ini设置,让我们说precision = 8

342349.23 - 341765.07 = 584.16 // voila!

演示:http://codepad.org/r7o086sS

这有多糟糕?

1.如果我只需要精确的2位数字计算(钱),我可以依靠这个解决方案吗?

2.如果没有,你能为我提供一个清楚的例子,当这个解决方案失败?

编辑:3.哪个PHP.ini.precision值适合最好的两位数,钱计算

>请注意,我不能使用整数计算(float * 100 = cents),这太晚了。
>我不打算工作在高于10 ^ 6的数字
>我不需要比较数字

更新

@Baba回答是好的,但他使用精度= 20,精度= 6在他的测试…所以,我仍然不知道是否会工作或不工作。

请考虑以下内容

让我们说precision = 8,只有我做的是加法和减法 –

A B = C

A-B = C

问题1: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";
  }
}

but obviously 99999999 * 2 is too big job so I can’t run this test

问题2:如何估计/计算何时精确解决方法失败?没有这么疯狂的测试?有什么数学*,直接的答案吗?如何计算是要失败还是失败?

*我不需要知道浮点计算工作,但如果解决方法失败,如果你知道精度,范围A和B

请记住我真的知道分和bcmath是最好的解决方案。但仍然我不知道是解决方法失败或不减法和添加

介绍

浮点运算被许多人认为是一个深奥的主题。这是相当令人惊讶的,因为浮点在计算机系统中是普遍存在的。大多数分数不具有作为二进制分数的精确表示,因此存在一些四舍五入。一个好的开始是What Every Computer Scientist Should Know About Floating-Point Arithmetic

问题

问题1

Can I rely on this solution if I need just precise 2 digits calculations (money)?

答案1

如果你需要精确的2位数,那么答案是否定的,你不能使用PHP精度设置来确定一个2位十进制的所有时间,即使你不打算工作的数字高于10 ^ 6。

在计算期间,如果长度小于8,则可能增加精度长度

问题2

If not can you provide me a clear example when this solutions fails?

答案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

Which PHP.ini.precision value suits best two digits,money calculations?

答案3

精确和金钱计算是两个不同的事情…它不是一个好主意,使用PHP精度作为您的财务计算或浮点长度的基础

简单测试

Lest使用bcmath,number_format和简单减号运行一些示例

基础

$a = 342349.23;
$b = 341765.07;

实施例A

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,PHP_EOL;

输出

584.15999999997438863
584.15999999999996817    <----- Round having a party 
584.16
584.15  <-------- here is 15 because precision value is 20

实施例B

ini_set('precision',14); // change to  14 
echo $a - $b,PHP_EOL;

输出

584.15999999997
584.16
584.16
584.16  <-------- at 14 it changed to 16

实施例C.

ini_set('precision',6); // change to  6 
echo $a - $b,PHP_EOL;

输出

584.16
584.16
584.16
584.00  <--- at 6 it changed to 00

实施例D

ini_set('precision',3); // change to 3
echo $a - $b,PHP_EOL;

输出

584
584
584.16   <-------------------------------- They only consistent value 
0.00 <--- at 3 .. everything is gone

结论

忘记浮点,只计算在分,然后除以100,如果太晚只是简单地使用number_format它看起来一致的我。

更新

Question 1: Is precision workaround gonna fail for numbers between 0..999999.99,where A and B is a number with decimal places? If so please provide me an example

形式0到999999.99在0.01的增量是大约99,999,999的你的循环的组合可能性是9,800,000,000我真的不认为任何人都想为你运行这样的测试。

由于浮点是具有有限精度的二进制数,试图设置精度将具有有限的效果以确保精度这里是一个简单的测试:

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.4
1.0408341E-17     <--- am sure you would expect 0.00 here ;

尝试

echo round($i,PHP_EOL;
echo number_format($i,PHP_EOL;

输出

0
0.00    <------ still confirms number_format is most accurate to maintain 2 digit

Question 2: How to estimate/calculate when precision workaround fails? Without such crazy tests? Is there any mathematical*,straight answer for it? How to calculate is gonna to fail or not?

事实仍然是Floating PointAccuracy Problems,但对于数学解决方案,你可以看看

> Machine precision and backward error analysis
> Minimizing the effect of accuracy problems

i don’t need to kNow floating point calculations works,but when workaround fails if you kNow precision,and range of A and B

不知道那个语句意味着什么

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...