Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 1.8.5, 1.10.2
-
Fix Version/s: 1.10.3
-
Component/s: Zend_Locale
-
Labels:None
Description
I found this while analysing a bug in Magento - currency values were not displaying correctly. Values were occasionally being display one unit (one Pound) lower than they should be. The following code fragment demonstrates the problem:
require_once("Zend/Loader.php");
require_once("Zend/Locale/Format.php");
foreach(array(3.99, 3.994, 3.995, 3.999, 4.00) as $value) {
$rounded = round($value, 2);
$formatted = Zend_Locale_Format::toNumber($value, array('precision' => 2));
echo "Value=$value Rounded=$rounded Formatted=$formatted ";
if ((float)$rounded == (float)$formatted) {
echo "PASS<br />";
} else {
echo "** FAIL **<br />";
}
}
This displays the following output:
Value=3.99 Rounded=3.99 Formatted=3.99 PASS
Value=3.994 Rounded=3.99 Formatted=3.99 PASS
Value=3.995 Rounded=4 Formatted=3.00 ** FAIL **
Value=3.999 Rounded=4 Formatted=3.00 ** FAIL **
Value=4 Rounded=4 Formatted=4.00 PASS
Note that when 0.995 is rounded up, the unit is not carried forward beyond the decimal point. Looking at the code, the number part above and below the decimal point is formatted separately, with the integer part done first, and the decimal part done second (losing the unit if it overflows).
Magento uses Zend 8.something (8.5?) but this error is still present in Zend 10.2 (which is where the above results came from).
This is no failure.
From the API doc:
" * The 'precision' option of a value is used to truncate or stretch extra digits. -1 means not to touch the extra digits."
For rounding you need to use Zend_Locale_Math::round()