"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Can I Rely on PHP's `php.ini` Precision for Accurate Money Calculations?

Can I Rely on PHP's `php.ini` Precision for Accurate Money Calculations?

Published on 2024-11-19
Browse:701

 Can I Rely on PHP's `php.ini` Precision for Accurate Money Calculations?

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

Introduction

Floating-point arithmetic, a complex subject often misunderstood, pervades modern computer systems. As most fractional numbers lack an exact binary representation, rounding unavoidably occurs. Understanding the nuances of floating-point operations is crucial, as outlined in "What Every Computer Scientist Should Know About Floating-Point Arithmetic."

Questions and Answers


Question 1: Can I use the precision workaround for precise 2-digit calculations (e.g., money)?

Answer: No, you cannot rely on php.ini precision settings for consistent 2-digit accuracy, even for numbers below 10^6, because the precision length can increase during calculations.

Question 2: Provide a clear example where the precision workaround fails.

Answer: Consider the following example with a 10% discount applied only to the first kilogram:

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 the first kg
echo ($a * $q) - $b;

Output: 14.5824

Question 3: Which php.ini.precision value is suitable for 2-digit money calculations?

Answer: PHP precision settings are not a reliable basis for financial calculations or floating-point precision. It's better to use specialized libraries or methods.

Example Calculations

Let's examine various examples to illustrate the accuracy limitations:

$a = 342349.23;
$b = 341765.07;

// Example A: precision = 20
echo $a - $b, PHP_EOL; // 584.15999999997438863
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.15999999999996817 (rounding introduces instability)
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.15

// Example B: 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

// Example C: 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

// Example D: 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 (consistent)
echo bcsub($a, $b, 2), PHP_EOL; // 0.00

These examples demonstrate the inconsistencies in relying on PHP precision settings for accurate calculations.

Conclusion

For reliable financial calculations, forget about floating-point and use cents or consider the number_format function for consistent 2-digit accuracy.

Update

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;
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3