ZF-2878: bcmath extension used by Zend_Locale doesn't support scientific notation for floats representation.


bcmath extension uses strings as an input. Some floats are automatically written using scientific notation while they are converted to strings (like '1.234E-6').

bcmath extension skips exponent part of the number (e.g. '1.234E-6' => '1.234'). That produces wrong results of mathimatical operations with some numbers.

Hopefully, bcmath functions are not used directly within Zend Framework (except some big integers arithmetic within Zend_OpenId which is not affected by this problem). So we can proxy bcmath calls and perform correct numbers transformation.

That also may help to solve problems with some locales having ',' as decimal separator.


We can solve this by adding this code to Zend_Locale_Math::normalize:

public static function normalize($value)
  // Handle exponential notation
  $parts = preg_split('/e/i', $value);
  if (count($parts) > 1) {
    $value = bcmul($parts[0], bcpow(10, $parts[1]));
  return $value;

Test :

$this->assertEquals('1000', Zend_Locale_Math::normalize('1e3'));
$this->assertEquals('1000', Zend_Locale_Math::normalize('1E3'));
$this->assertEquals('1234', Zend_Locale_Math::normalize('1.234E3'));
$this->assertEquals('0.001', Zend_Locale_Math::normalize('1e-3'));

$this->assertEquals('12', Zend_Locale_Math::round('1.23e1'));
$this->assertEquals('12.3', Zend_Locale_Math::round('1.23e1', 1));

Note : bcmath is required.

{quote} Hopefully, bcmath functions are not used directly within Zend Framework {quote}

bcmath functions (and scientific notation) are used in Zend_Measure.

There are several places where bcmath are used. But your code can not be used, as it does not work when bcmath is not available.

You can not use bcmath functions on a class which is used as workaround when no bcmath is installed.

Feature added with r13500