En el modelo tax/Sales_Total_Quote_Tax
, hay un método _deltaRound()
que redondea un precio. Agrega un pequeño delta, para detener el comportamiento no determinista al redondear 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;
}
Pero almacena un delta. Si no puede encontrar ese delta almacenado, lo inventa. ¿Por qué? Por lo que puedo decir, esto conduce a resultados diferentes con operaciones idénticas.
Digamos que tenemos un $price
3.595 y no tenemos un caché $delta
. A medida que avanzamos por el método, obtendremos $ delta = 0.000001. Entonces obtenemos $price
= 3.595001, que se redondea a 3.60, por lo que tenemos un nuevo $delta
de -0.004999. Y devolvemos 3.60.
Excepto que ahora tenemos un delta, así que hagámoslo de nuevo, con $price
= 3.595. $price
= 3.595 - 0.004999 = 3.590001
Que si redondeamos, obtenemos 3.59. Diferentes respuestas
Me parece que cualquier algoritmo de redondeo utilizado debería al menos dar la misma respuesta cada vez que se ejecuta con los mismos argumentos, pero no esta vez.