Handling Floating-Point Precision in PHP: Common Issues and Solutions with bcmath

This article explains PHP floating-point precision issues, demonstrates common arithmetic errors, and shows how to use the bcmath extension and various rounding functions such as floor, ceil, round, and number_format to achieve accurate numeric calculations in backend development.

php Courses
php Courses
php Courses
Handling Floating-Point Precision in PHP: Common Issues and Solutions with bcmath

Introduction

PHP floating-point numbers have limited precision, which can cause noticeable errors in financial, e‑commerce, and other applications. PHP typically uses the IEEE‑754 double‑precision format, giving a maximum relative error of 1.11e-16, and non‑basic operations may produce larger errors. Never trust a floating-point result to be exact or compare two floating-point numbers for equality; use arbitrary‑precision functions or the gmp extension when higher accuracy is required.

1. Operations

Incorrect (using native floating‑point)

// addition
$a = 0.1; $b = 0.7; $c = intval(($a + $b) * 10); echo $c."<br>"; // output: 7
// subtraction
$a = 100; $b = 99.98; $c = $a - $b; echo $c."<br>"; // output: 0.019999999999996
// multiplication
$a = 0.58; $b = 100; $c = intval($a * $b); echo $c."<br>"; // output: 57
// division
$a = 0.7; $b = 0.1; $c = intval($a / $b); echo $c."<br>"; // output: 6

Correct (using bcmath )

// addition
$a = 0.1; $b = 0.7; $c = intval(bcadd($a, $b, 1) * 10); echo $c."<br>"; // output: 8
// subtraction
$a = 100; $b = 99.98; $c = bcsub($a, $b, 2); echo $c."<br>"; // output: 0.02
// multiplication
$a = 0.58; $b = 100; $c = intval(bcmul($a, $b)); echo $c."<br>"; // output: 58
// division
$a = 0.7; $b = 0.1; $c = intval(bcdiv($a, $b)); echo $c."<br>"; // output: 7

The bcmath extension also provides functions such as bccomp (compare), bcmod (modulus), bcpow (power), bcpowmod (power with modulus), bcscale (set default scale), and bcsqrt (square root).

2. Common Numeric Handling Methods

Floor (round down)

echo floor(5.1); // output: 5
echo floor(8.8); // output: 8

Ceil (round up)

echo ceil(5.1); // output: 6
echo ceil(8.8); // output: 9

Standard rounding

echo round(5.1); // output: 5
echo round(8.8); // output: 9
// round to two decimal places
echo round(5.123, 2); // output: 5.12
echo round(8.888, 2); // output: 8.89
// truncate without rounding
echo substr(round(5.12345, 3), 0, -1); // output: 5.12
echo substr(round(8.88888, 3), 0, -1); // output: 8.88

Banker's rounding

Rules: When the digit after the rounding position is 5, look at subsequent digits; if any are non‑zero, round up. If the trailing digits are all zero, round to the nearest even digit (banker's rounding). Example:

1.2849 = 1.28  // round down
1.2866 = 1.29  // round up
1.2851 = 1.29  // round up because digits after 5 are non‑zero
1.2850 = 1.28  // round down because preceding digit (8) is even
1.2750 = 1.28  // round up because preceding digit (7) is odd

Number formatting (thousands separator)

echo number_format('10000.98', 2, '.', ','); // output: 10,000.98
echo number_format('340888999', 2, '.', ','); // output: 340,888,999.00
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendPHPprecisionfloating-pointRoundingbcmath
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.