我可以依赖PHP php.ini精确解决方法为浮点问题
我发现一些解决方法为
floating point problem在PHP:
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),这太晚了。 更新 @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 问题2:如何估计/计算何时精确解决方法失败?没有这么疯狂的测试?有什么数学*,直接的答案吗?如何计算是要失败还是失败? *我不需要知道浮点计算工作,但如果解决方法失败,如果你知道精度,范围A和B 请记住我真的知道分和bcmath是最好的解决方案。但仍然我不知道是解决方法失败或不减法和添加
介绍
浮点运算被许多人认为是一个深奥的主题。这是相当令人惊讶的,因为浮点在计算机系统中是普遍存在的。大多数分数不具有作为二进制分数的精确表示,因此存在一些四舍五入。一个好的开始是What Every Computer Scientist Should Know About Floating-Point Arithmetic 问题 问题1
答案1 如果你需要精确的2位数,那么答案是否定的,你不能使用php精度设置来确定一个2位十进制的所有时间,即使你不打算工作的数字高于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
答案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它看起来一致的我。 更新
形式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
事实仍然是Floating Point有Accuracy Problems,但对于数学解决方案,你可以看看 > Machine precision and backward error analysis
不知道那个语句意味着什么 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |