ZF-9319: Locale does not carry rounding up to units

Issue Type: Bug Created: 2010-03-03T16:20:21.000+0000 Last Updated: 2010-03-14T05:03:14.000+0000 Status: Resolved Fix version(s): - 1.10.3 (01/Apr/10)

Reporter: Jason Judge (judgej) Assignee: Thomas Weidner (thomas) Tags: - Zend_Locale

Related issues: Attachments:


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
"; } else { echo "** FAIL **
"; } }

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).


Posted by Thomas Weidner (thomas) on 2010-03-04T11:23:40.000+0000

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()

Posted by Jason Judge (judgej) on 2010-03-04T11:56:07.000+0000

Could you explain that specification? I'm not sure how "truncate or stretch extra digits" can be interpreted to mean "3.995 should be formatted as 3.00", and even if it did, exactly what use such a transform is. At a stretch I would accept "truncate to a precision of 2" to mean 3.995 is formatted as 3.99. But 3.00 - surely not.

This method is actually called in a long chain from Magento to format monetary values, and goes via the Zend_Currency methods, so whether Zend_Format or Zend_Math is used to format that currency, is pretty much out of the hands of the application.

Posted by Jason Judge (judgej) on 2010-03-04T11:59:38.000+0000

I would also be interested to know what tests are performed for this boundary condition. If any, is it accepted that 3.994 be formatted as "3.99" and 3.995 be formatted as "3.00"? If no tests are run, then can some be set up so people are very clear that this is the expected functionality?

Posted by Thomas Weidner (thomas) on 2010-03-14T05:03:14.000+0000

Implemented using precision without format with r21493

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.