Dans le modèle tax/Sales_Total_Quote_Tax
, il existe une méthode _deltaRound()
qui arrondit un prix. Il ajoute un petit delta pour arrêter le comportement non déterministe lors de l'arrondi à 0,5.
/**
* Round price based on previous rounding operation delta
*
* @param float $price
* @param string $rate
* @param bool $direction price including or excluding tax
* @param string $type
* @return float
*/
protected function _deltaRound($price, $rate, $direction, $type = 'regular')
{
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;
$this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
$price = $this->_calculator->round($price);
}
return $price;
}
Mais il stocke un delta. S'il ne trouve pas un tel delta stocké, il en crée un. Pourquoi? Comme tar que je peux dire, cela conduit à des résultats différents avec des opérations identiques.
Disons que nous avons un $price
3.595, et nous n'avons pas de cache $delta
. En parcourant la méthode, nous obtiendrons $ delta = 0,000001. Nous obtenons alors $price
= 3,595001, qui arrondit à 3,60, nous avons donc un nouveau $delta
de -0,004999. Et nous retournons 3,60.
Sauf que maintenant nous avons un delta, alors recommençons, avec $price
= 3,595. $price
= 3,595 - 0,004999 = 3,590001
Si nous arrondissons, nous obtenons 3,59. Des réponses différentes.
Il me semble que tout algorithme d'arrondi utilisé devrait au moins donner la même réponse à chaque fois qu'il est exécuté avec les mêmes arguments, mais pas cette fois.