$precision)) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("addition overflow: $op1 + $op2 != $result", $op1, $op2, $result); } return self::round(self::normalize($result), $scale); } public static function Sub($op1, $op2, $scale = null) { if ($scale === null) { $scale = Zend_Locale_Math_PhpMath::$defaultScale; $precision = Zend_Locale_Math_PhpMath::$defaultPrecision; } else { $precision = pow(10, -$scale); } if (empty($op1)) { $op1 = 0; } $op1 = self::normalize($op1); $op2 = self::normalize($op2); $result = $op1 - $op2; if (is_infinite($result) or (abs($result + $op2 - $op1) > $precision)) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("subtraction overflow: $op1 - $op2 != $result", $op1, $op2, $result); } return self::round(self::normalize($result), $scale); } public static function Pow($op1, $op2, $scale = null) { 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 $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'; throw new Zend_Locale_Math_Exception("power overflow: $op1 ^ $op2", $op1, $op2, $result); } return self::round(self::normalize($result), $scale); } public static function Mul($op1, $op2, $scale = null) { if ($scale === null) { $scale = Zend_Locale_Math_PhpMath::$defaultScale; } if (empty($op1)) { $op1 = 0; } $op1 = self::normalize($op1); $op2 = self::normalize($op2); $result = $op1 * $op2; if (is_infinite($result) or is_nan($result)) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("multiplication overflow: $op1 * $op2 != $result", $op1, $op2, $result); } return self::round(self::normalize($result), $scale); } public static function Div($op1, $op2, $scale = null) { if ($scale === null) { $scale = Zend_Locale_Math_PhpMath::$defaultScale; } if (empty($op2)) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("can not divide by zero", $op1, $op2, null); } if (empty($op1)) { $op1 = 0; } $op1 = self::normalize($op1); $op2 = self::normalize($op2); $result = $op1 / $op2; if (is_infinite($result) or is_nan($result)) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("division overflow: $op1 / $op2 != $result", $op1, $op2, $result); } return self::round(self::normalize($result), $scale); } public static function Sqrt($op1, $scale = null) { if ($scale === null) { $scale = Zend_Locale_Math_PhpMath::$defaultScale; } if (empty($op1)) { $op1 = 0; } $op1 = self::normalize($op1); $result = sqrt($op1); if (is_nan($result)) { return NULL; } return self::round(self::normalize($result), $scale); } public static function Mod($op1, $op2) { if (empty($op1)) { $op1 = 0; } if (empty($op2)) { return NULL; } $op1 = self::normalize($op1); $op2 = self::normalize($op2); if ((int)$op2 == 0) { return NULL; } $result = $op1 % $op2; if (is_nan($result) or (($op1 - $result) % $op2 != 0)) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("modulus calculation error: $op1 % $op2 != $result", $op1, $op2, $result); } return self::normalize($result); } public static function Comp($op1, $op2, $scale = null) { if ($scale === null) { $scale = Zend_Locale_Math_PhpMath::$defaultScale; } if (empty($op1)) { $op1 = 0; } $op1 = self::normalize($op1); $op2 = self::normalize($op2); if ($scale <> 0) { $op1 = self::round($op1, $scale); $op2 = self::round($op2, $scale); } else { $op1 = ($op1 > 0) ? floor($op1) : ceil($op1); $op2 = ($op2 > 0) ? floor($op2) : ceil($op2); } if ($op1 > $op2) { return 1; } else if ($op1 < $op2) { return -1; } return 0; } public static function Scale($scale) { if ($scale > 9) { require_once 'Zend/Locale/Math/Exception.php'; throw new Zend_Locale_Math_Exception("can not scale to precision $scale", $scale, null, null); } self::$defaultScale = $scale; self::$defaultPrecision = pow(10, -$scale); return true; } } Zend_Locale_Math_PhpMath::disable(); // disable use of bcmath functions