Przeglądaj źródła

[ZF-6060] Zend_Locale_Math:

- fixed rounding for negative values whith enabled bcmath

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@15585 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 lat temu
rodzic
commit
466ac809ed

+ 1 - 1
library/Zend/Locale.php

@@ -440,7 +440,7 @@ class Zend_Locale
     /**
      * Returns the language part of the locale
      *
-     * @return string - language
+     * @return string
      */
     public function getLanguage()
     {

+ 15 - 2
library/Zend/Locale/Math.php

@@ -67,7 +67,8 @@ class Zend_Locale_Math
         if (self::$_bcmathDisabled) {
             return self::normalize(round($op1, $precision));
         }
-        $op1 = trim(self::normalize($op1));
+
+        $op1    = trim(self::normalize($op1));
         $length = strlen($op1);
         if (($decPos = strpos($op1, '.')) === false) {
             $op1 .= '.0';
@@ -77,10 +78,12 @@ class Zend_Locale_Math
         if ($precision < 0 && abs($precision) > $decPos) {
             return '0';
         }
+
         $digitsBeforeDot = $length - ($decPos + 1);
         if ($precision >= ($length - ($decPos + 1))) {
             return $op1;
         }
+
         if ($precision === 0) {
             $triggerPos = 1;
             $roundPos   = -1;
@@ -91,22 +94,31 @@ class Zend_Locale_Math
             $triggerPos = $precision;
             $roundPos   = $precision -1;
         }
+
         $triggerDigit = $op1[$triggerPos + $decPos];
         if ($precision < 0) {
             // zero fill digits to the left of the decimal place
             $op1 = substr($op1, 0, $decPos + $precision) . str_pad('', abs($precision), '0');
         }
+
         if ($triggerDigit >= '5') {
             if ($roundPos + $decPos == -1) {
                 return str_pad('1', $decPos + 1, '0');
             }
+
             $roundUp = str_pad('', $length, '0');
             $roundUp[$decPos] = '.';
             $roundUp[$roundPos + $decPos] = '1';
-            return bcadd($op1, $roundUp, $precision);
+
+            if ($op1 > 0) {
+                return self::Add($op1, $roundUp, $precision);
+            } else {
+                return self::Sub($op1, $roundUp, $precision);
+            }
         } elseif ($precision >= 0) {
             return substr($op1, 0, $decPos + ($precision ? $precision + 1: 0));
         }
+
         return (string) $op1;
     }
 
@@ -186,6 +198,7 @@ class Zend_Locale_Math
     {
         $op1 = self::exponent($op1, $scale);
         $op2 = self::exponent($op2, $scale);
+
         return bcadd($op1, $op2, $scale);
     }
 

+ 7 - 7
library/Zend/Locale/Math/PhpMath.php

@@ -45,7 +45,7 @@ class Zend_Locale_Math_PhpMath extends Zend_Locale_Math
         self::$sqrt  = array('Zend_Locale_Math_PhpMath', 'Sqrt');
         self::$mod   = array('Zend_Locale_Math_PhpMath', 'Mod');
         self::$scale = array('Zend_Locale_Math_PhpMath', 'Scale');
-        
+
         self::$defaultScale     = 0;
         self::$defaultPrecision = 1;
     }
@@ -53,7 +53,7 @@ class Zend_Locale_Math_PhpMath extends Zend_Locale_Math
     public static $defaultScale;
     public static $defaultPrecision;
 
-    
+
     public static function Add($op1, $op2, $scale = null)
     {
         if ($scale === null) {
@@ -105,14 +105,14 @@ class Zend_Locale_Math_PhpMath extends Zend_Locale_Math
         if ($scale === null) {
             $scale = Zend_Locale_Math_PhpMath::$defaultScale;
         }
-        
+
         $op1 = self::normalize($op1);
         $op2 = self::normalize($op2);
-        
+
         // BCMath extension doesn't use decimal part of the power
-        // Provide the same behavior 
+        // Provide the same behavior
         $op2 = ($op2 > 0) ? floor($op2) : ceil($op2);
-        
+
         $result = pow($op1, $op2);
         if (is_infinite($result)  or  is_nan($result)) {
             require_once 'Zend/Locale/Math/Exception.php';
@@ -211,7 +211,7 @@ class Zend_Locale_Math_PhpMath extends Zend_Locale_Math
         if ($scale === null) {
             $scale     = Zend_Locale_Math_PhpMath::$defaultScale;
         }
-        
+
         if (empty($op1)) {
             $op1 = 0;
         }

+ 3 - 0
tests/Zend/Locale/FormatTest.php

@@ -297,6 +297,9 @@ class Zend_Locale_FormatTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(    '1234567-', Zend_Locale_Format::toInteger(-1234567.12345,   array('locale' => 'ar_QA')));
         $this->assertEquals(  '12,34,567',  Zend_Locale_Format::toInteger( 1234567.12345,   array('locale' => 'dz_BT')));
         $this->assertEquals('-(1.234.567)', Zend_Locale_Format::toInteger(-1234567.12345,   array('locale' => 'mk_MK')));
+
+        $this->assertEquals('-45', Zend_Locale_Format::toInteger(-45.23, $options));
+        $this->assertEquals('-46', Zend_Locale_Format::toInteger(-45.99, $options));
     }
 
 

+ 20 - 0
tests/Zend/Locale/MathTest.php

@@ -1635,4 +1635,24 @@ class Zend_Locale_MathTest extends PHPUnit_Framework_TestCase
         $this->assertEquals('-1', Zend_Locale_Math::Comp(2, '1e3'));
         $this->assertEquals('0', Zend_Locale_Math::Comp('1e3', '1e3'));
     }
+
+    public function testNegativeRounding()
+    {
+        $this->assertEquals(               '-3', Zend_Locale_Math::round('-3.4'));
+        $this->assertEquals(        round(-3.4), Zend_Locale_Math::round('-3.4'));
+        $this->assertEquals(               '-4', Zend_Locale_Math::round('-3.5'));
+        $this->assertEquals(        round(-3.5), Zend_Locale_Math::round('-3.5'));
+        $this->assertEquals(               '-4', Zend_Locale_Math::round('-3.6'));
+        $this->assertEquals(        round(-3.6), Zend_Locale_Math::round('-3.6'));
+        $this->assertEquals(               '-4', Zend_Locale_Math::round('-3.6', 0));
+        $this->assertEquals(      round(-3.6,0), Zend_Locale_Math::round('-3.6', 0));
+        $this->assertEquals(            '-1.96', Zend_Locale_Math::round('-1.95583', 2), '', 0.02);
+        $this->assertEquals(  round(-1.95583,2), Zend_Locale_Math::round('-1.95583', 2), '', 0.02);
+        $this->assertEquals(           -1242000, Zend_Locale_Math::round('-1241757', -3), '', 250);
+        $this->assertEquals(round(-1241757, -3), Zend_Locale_Math::round('-1241757', -3), '', 250);
+        $this->assertEquals(              -5.05, Zend_Locale_Math::round('-5.045', 2), '', 0.02);
+        $this->assertEquals(   round(-5.045, 2), Zend_Locale_Math::round('-5.045', 2), '', 0.02);
+        $this->assertEquals(              -5.06, Zend_Locale_Math::round('-5.055', 2), '', 0.02);
+        $this->assertEquals(   round(-5.055, 2), Zend_Locale_Math::round('-5.055', 2), '', 0.02);
+    }
 }