Is PHP's `precision` Workaround Reliable for Precise 2-Digit Money Calculations?

Linda Hamilton
Release: 2024-11-07 06:39:02
Original
541 people have browsed it

Is PHP's `precision` Workaround Reliable for Precise 2-Digit Money Calculations?

Can I Rely on PHP PHP.INI Precision Workaround for Floating Point Issue?

Introduction

Floating-point arithmetic involves representing fractional numbers as binary fractions, which may not have exact representations. This can lead to rounding errors.

Question 1:

Can this workaround ensure precise 2-digit calculations for money?

Answer 1:

No. PHP precision settings cannot guarantee precise 2-digit calculations, as precision can be increased during calculations.

Question 2:

Example of when the workaround fails:

ini_set('precision', 8);
$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; // result: 14.5824 (not precise for money calculations)
Copy after login

Question 3:

Which php.ini.precision value suits best for 2-digit money calculations?

Answer 3:

PHP precision is not a recommended metric for precise financial calculations.

Simple Test

Using bcmath, number_format, and subtraction:

$a = 342349.23;
$b = 341765.07;

ini_set('precision', 20);
echo $a - $b, PHP_EOL; // 584.15999999997438863
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.15999999999996817 (rounding issue)
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.15 (precision set to 20)

ini_set('precision', 14);
echo $a - $b, PHP_EOL; // 584.15999999997
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.16 (precision set to 14)

ini_set('precision', 6);
echo $a - $b, PHP_EOL; // 584.16
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.00 (precision set to 6)

ini_set('precision', 3);
echo $a - $b, PHP_EOL; // 584
echo floatval(round($a - $b, 2)), PHP_EOL; // 584
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 0.00 (precision set to 3)
Copy after login

Conclusion

Using number_format for money calculations is recommended for consistency. Storing in cents is also an option.

Update

Question 1: Will precision workaround fail for numbers between 0..999999.99?

Answer 1:

Yes, due to the large number of combinations, a full test is impractical.

Example:

$a = 0.19;
$b = 0.16;
...
$h = $a + $b + ...; // Total value: 0.4

$i = $h - $a - $b - ...; // Result: 1.0408341E-17 (expected: 0.00)
Copy after login

Question 2: How to estimate when precision workaround fails?

Answer 2:

Mathematical solutions exist, but it's not within the scope of this discussion.

The above is the detailed content of Is PHP's `precision` Workaround Reliable for Precise 2-Digit Money Calculations?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!