Im Modell tax/Sales_Total_Quote_Tax
gibt es eine Methode _deltaRound()
, die einen Preis rundet. Es wird ein kleines Delta hinzugefügt, um nichtdeterministisches Verhalten beim Runden von 0,5 zu stoppen.
/**
* 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;
}
Aber es speichert ein Delta. Wenn es ein solches gespeichertes Delta nicht finden kann, bildet es eines. Warum? Soweit ich das beurteilen kann, führt dies bei identischen Operationen zu unterschiedlichen Ergebnissen.
Nehmen wir an, wir haben einen $price
Wert von 3,595 und keinen zwischengespeicherten Wert $delta
. Während wir die Methode durchlaufen, erhalten wir $ delta = 0.000001. Wir bekommen dann $price
= 3.595001, was auf 3.60 rundet, also haben wir einen neuen $delta
von -0.004999. Und wir geben 3,60 zurück.
Außer jetzt haben wir ein Delta, also lass es uns noch einmal machen, mit $price
= 3.595. $price
= 3,595 - 0,004999 = 3,590001
Wenn wir runden, erhalten wir 3,59. Unterschiedliche Antworten.
Es scheint mir, dass jeder verwendete Rundungsalgorithmus jedes Mal, wenn er mit denselben Argumenten ausgeführt wird, mindestens dieselbe Antwort geben sollte, diesmal jedoch nicht.