UPSTREAM FIX

magento2-35730: Product prices returning a tiny rounding excess when tax is applied

Community fix magento2-35730 merged into magento/magento2 on 2026-01-09, released in 2.4.9; applies cleanly to 33 releases from 2.4.6 to 2.4.8-p5.

Fixes product prices returning a tiny rounding excess when tax is applied edited

Pull request title
Rounding problem on prices when adding tax to display prices
Pull request
magento/magento2#35730
Issues
#18025 human
Author
@ravi-chandra3197
Merged
2026-01-09
Fixed in
2.4.9
Reported on
—
Categories
Price/Tax
Components
magento/module-tax

Labels

Area
Catalog
Component
Tax
Priority
P3
Severity
S4
Reported on (labels)
2.4.x

Issue

Title and steps come from the upstream issue and pull request.

Description

1. Magento\Framework\Pricing\Price\AbstractPrice returns value of 8.750001. This is visible example data-price-amount se to price wrapper element. See screenshot.
![image](https://user-images.githubusercontent.com/5977769/45406745-80522d00-b678-11e8-842b-123a9c1e1484.png)

Steps to reproduce

1. Set _Configuration > Tax > Calculation Settings_ to following:
![tax_calculation_settings](https://user-images.githubusercontent.com/5977769/45406384-682dde00-b677-11e8-85ec-e1400d2bc6ec.png)
2. Set _Configuration > Tax > Price Display Settings_ to _Including Tax_

Expected result

1. Tax should be added to price set in product data when getting amount from classes extending Magento\Framework\Pricing\Price\AbstractPrice. Example Affirm Water Bottle with price of 7.00 with tax of 25 percent should result final value of 8.75

Actual result

1. Magento\Framework\Pricing\Price\AbstractPrice returns value of 8.750001. This is visible example data-price-amount se to price wrapper element. See screenshot.
![image](https://user-images.githubusercontent.com/5977769/45406745-80522d00-b678-11e8-842b-123a9c1e1484.png)


### Own findings

Problem seems to stem from Magento\Tax\Model\Calculation\AbstractCalculator. Calculator is adding delta of 0.000001 in deltaRound to prices, even if the $round is set to false and no rounding is happening.
    /**
     * Round price based on previous rounding operation delta
     *
     * @param float $price
     * @param string $rate
     * @param bool $direction
     * @param string $type
     * @param bool $round
     * @return float
     */
    protected function deltaRound($price, $rate, $direction, $type = self::KEY_REGULAR_DELTA_ROUNDING, $round = true)
    {
        if ($price) {
            $rate = (string)$rate;
            $type = $type . $direction;
            // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
            $delta = isset($this->roundingDeltas[$type][$rate]) ?
                $this->roundingDeltas[$type][$rate] :
                0.000001;
            $price += $delta;
            $roundPrice = $price;
            if ($round) {
                $roundPrice = $this->calculationTool->round($roundPrice);
            }
            $this->roundingDeltas[$type][$rate] = $price - $roundPrice;
            $price = $roundPrice;
        }
        return $price;
    }

Taken from the upstream issue.

Code match per tag

Each tag was checked with git apply --check against that tag's files. A clean match means the change applies; it is not a test result. Tags that already contain the fix are marked.

LineCode match per tagTests
2.4.6
2.4.6 clean 2.4.6-p1 clean 2.4.6-p2 clean 2.4.6-p3 clean 2.4.6-p4 clean 2.4.6-p5 clean 2.4.6-p6 clean 2.4.6-p7 clean 2.4.6-p8 clean 2.4.6-p9 clean 2.4.6-p10 clean 2.4.6-p11 clean 2.4.6-p12 clean 2.4.6-p13 clean 2.4.6-p14 clean 2.4.6-p15 clean
2.4.6: no test data 2.4.6-p1: no test data 2.4.6-p2: no test data 2.4.6-p3: no test data 2.4.6-p4: no test data 2.4.6-p5: no test data 2.4.6-p6: no test data 2.4.6-p7: no test data 2.4.6-p8: no test data 2.4.6-p9: no test data 2.4.6-p10: no test data 2.4.6-p11: no test data 2.4.6-p12: no test data 2.4.6-p13: no test data 2.4.6-p14: no test data 2.4.6-p15: no test data
2.4.7
2.4.7 clean 2.4.7-p1 clean 2.4.7-p2 clean 2.4.7-p3 clean 2.4.7-p4 clean 2.4.7-p5 clean 2.4.7-p6 clean 2.4.7-p7 clean 2.4.7-p8 clean 2.4.7-p9 clean 2.4.7-p10 clean
2.4.7: no test data 2.4.7-p1: no test data 2.4.7-p2: no test data 2.4.7-p3: no test data 2.4.7-p4: no test data 2.4.7-p5: no test data 2.4.7-p6: no test data 2.4.7-p7: no test data 2.4.7-p8: no test data 2.4.7-p9: no test data 2.4.7-p10: fails before, passes afterunit: fails before, passes after · integration: fails before, passes after
2.4.8
2.4.8 clean 2.4.8-p1 clean 2.4.8-p2 clean 2.4.8-p3 clean 2.4.8-p4 clean 2.4.8-p5 clean
2.4.8: no test data 2.4.8-p1: no test data 2.4.8-p2: no test data 2.4.8-p3: no test data 2.4.8-p4: no test data 2.4.8-p5: fails before, passes afterunit: fails before, passes after · integration: fails before, passes after
2.4.9
2.4.9 conflictcontains the fix
2.4.9: no test data

Triage

Model @cf/cloudflare/clef. Probability this is a bug fix: 97.6%. Probability it is security relevant: 0.6%.

Show the model's answers and probabilities
QuestionAnswerProbabilitiesConfidence
Change kindbugfixbugfix 96.6%, refactor 1.8%, tests_only 0.7%, feature 0.3%, dependency 0.3%, docs_only 0.2%92.1%
Areacatalogcatalog 53.5%, checkout 13.4%, other 12.3%23.5%
Reported versionunspecifiedunspecified 39.2%, 2.4.2-p2 1.5%, 2.4.0 1.3%14.9%
Scope0.86 of 21 54.5%, 0 29.9%, 2 15.6%11.7%
Risk1.32 of 22 55.0%, 0 22.9%, 1 22.0%10.6%
Worth backporting1.29 of 22 47.0%, 1 34.7%, 0 18.4%6.2%

Download

For cweagans/composer-patches, choose a version below and download the bundle. Copy its magento2-35730/ folder into patches/composer/, merge composer.patches.json into composer.json, then run composer install. Test files are always removed; paths are relative to each package root, using the default -p1 level.

Packages (1): magento/module-tax
Bundle README (what the ZIP ships)
# magento2-35730

Community fix merged upstream into magento/magento2, adapted by magento.watch.
This is not a patch published by Adobe.

Pull request: https://github.com/magento/magento2/pull/35730
Issue: https://github.com/magento/magento2/issues/18025
Author: @ravi-chandra3197
Source commit: a689c797e8260b18d61b3d17a23e24f5e7ff17de
Modifications: test files and documentation removed, paths rewritten relative to each Composer package.
Licence: OSL-3.0 / AFL-3.0, as the original Magento Open Source code.
Maintainer: Łukasz Bajsarowicz (@lbajsarowicz)

Licence: Magento Open Source code under OSL-3.0 and AFL-3.0. The bundle carries the original author, source commit and the list of modifications.

Sources

Łukasz Bajsarowicz
Built by

Łukasz Bajsarowicz, e-commerce architect

Magento and Adobe Commerce architecture, upgrades, performance and audits for merchants and agencies since 2015; magento.watch is the tooling I use on those projects.

Open source, maintained on weekends.