Esempio n. 1
0
 /**
  * Surprisingly, the results of this implementation of round()
  * prove better than the native PHP round(). For example, try:
  *   round(639.795, 2);
  *   round(267.835, 2);
  *   round(0.302515, 5);
  *   round(0.36665, 4);
  * then try:
  *   IfwPsn_Vendor_Zend_Locale_Math::round('639.795', 2);
  */
 public static function round($op1, $precision = 0)
 {
     if (self::$_bcmathDisabled) {
         $op1 = round($op1, $precision);
         if (strpos((string) $op1, 'E') === false) {
             return self::normalize(round($op1, $precision));
         }
     }
     if (strpos($op1, 'E') !== false) {
         $op1 = self::floatalize($op1);
     }
     $op1 = trim(self::normalize($op1));
     $length = strlen($op1);
     if (($decPos = strpos($op1, '.')) === false) {
         $op1 .= '.0';
         $decPos = $length;
         $length += 2;
     }
     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;
     } elseif ($precision > 0) {
         $triggerPos = $precision + 1;
         $roundPos = $precision;
     } else {
         $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';
         if ($op1 > 0) {
             if (self::$_bcmathDisabled) {
                 return IfwPsn_Vendor_Zend_Locale_Math_PhpMath::Add($op1, $roundUp, $precision);
             }
             return self::Add($op1, $roundUp, $precision);
         } else {
             if (self::$_bcmathDisabled) {
                 return IfwPsn_Vendor_Zend_Locale_Math_PhpMath::Sub($op1, $roundUp, $precision);
             }
             return self::Sub($op1, $roundUp, $precision);
         }
     } elseif ($precision >= 0) {
         return substr($op1, 0, $decPos + ($precision ? $precision + 1 : 0));
     }
     return (string) $op1;
 }
Esempio n. 2
0
 public static function Scale($scale)
 {
     if ($scale > 9) {
         require_once IFW_PSN_LIB_ROOT . 'IfwPsn/Vendor/Zend/Locale/Math/Exception.php';
         throw new IfwPsn_Vendor_Zend_Locale_Math_Exception("can not scale to precision {$scale}", $scale, null, null);
     }
     self::$defaultScale = $scale;
     self::$defaultPrecision = pow(10, -$scale);
     return true;
 }