An Unexpected Test Failure
That kind of version-switching mistake later pushed me to set up a Laradock workflow for multiple PHP versions, where the correct PHP version is selected automatically for each project.


The screenshots show the result of running the exact same test on PHP 8.3 and PHP 8.4. No code changes were made, only the PHP version was different.
<?php declare(strict_types=1); namespace Tests\Unit; use PHPUnit\Framework\TestCase; final class RoundBehaviorTest extends TestCase{ public function testRoundBehaviorBetweenPhpVersions(): void { $totalCommission = 123.456 + 78.999; $commissionWithoutVat = round(168.7125, 2); $commissionVat = round( $totalCommission - $commissionWithoutVat, 2, ); $this->assertSame(33.75, $commissionVat); }}What Changed in PHP 8.4
The most interesting part was that both PHP versions passed the same intermediate value to round(): 33.74499999999997613.
On PHP 8.3, it was rounded to 33.75, while PHP 8.4 returned 33.74. That small difference was enough to make a previously passing test fail.
PHP 8.4 changed how round() handles values located near a rounding boundary. Previously, the function tried to behave as if a float were an exact decimal value and could treat numbers extremely close to the boundary as the next halfway value.
Starting with PHP 8.4, round() uses the actual binary floating-point value. In this example, the function does not receive an exact 33.745, but:
33.74499999999997613
This value is slightly lower than 33.745, so rounding it to two decimal places produces 33.74.
PHP 8.3 compensated for this floating-point difference and returned 33.75, while PHP 8.4 no longer treats the value as an exact halfway case. That change in edge-case handling is what caused the test to fail.
PHP 8.4 also introduced the RoundingMode enum and four additional rounding modes. However, those new modes are not the cause of this particular result—the difference comes from the updated handling of the underlying floating-point value.
This case was also a good reminder that when upgrading a Laravel project to a newer PHP version, it is not enough to confirm that the dependencies install successfully. I also need to run the real test suite and check whether the runtime itself behaves differently.



