/** * 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; }
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; }