00001 <?php
00035 class Zend_Locale_Math
00036 {
00037
00038 public static $_bcmathDisabled = false;
00039
00040 public static $add = array('Zend_Locale_Math', 'Add');
00041 public static $sub = array('Zend_Locale_Math', 'Sub');
00042 public static $pow = array('Zend_Locale_Math', 'Pow');
00043 public static $mul = array('Zend_Locale_Math', 'Mul');
00044 public static $div = array('Zend_Locale_Math', 'Div');
00045 public static $comp = array('Zend_Locale_Math', 'Comp');
00046 public static $sqrt = array('Zend_Locale_Math', 'Sqrt');
00047 public static $mod = array('Zend_Locale_Math', 'Mod');
00048 public static $scale = 'bcscale';
00049
00050 public static function isBcmathDisabled()
00051 {
00052 return self::$_bcmathDisabled;
00053 }
00054
00065 public static function round($op1, $precision = 0)
00066 {
00067 if (self::$_bcmathDisabled) {
00068 return self::normalize(round($op1, $precision));
00069 }
00070
00071 $op1 = trim(self::normalize($op1));
00072 $length = strlen($op1);
00073 if (($decPos = strpos($op1, '.')) === false) {
00074 $op1 .= '.0';
00075 $decPos = $length;
00076 $length += 2;
00077 }
00078 if ($precision < 0 && abs($precision) > $decPos) {
00079 return '0';
00080 }
00081
00082 $digitsBeforeDot = $length - ($decPos + 1);
00083 if ($precision >= ($length - ($decPos + 1))) {
00084 return $op1;
00085 }
00086
00087 if ($precision === 0) {
00088 $triggerPos = 1;
00089 $roundPos = -1;
00090 } elseif ($precision > 0) {
00091 $triggerPos = $precision + 1;
00092 $roundPos = $precision;
00093 } else {
00094 $triggerPos = $precision;
00095 $roundPos = $precision -1;
00096 }
00097
00098 $triggerDigit = $op1[$triggerPos + $decPos];
00099 if ($precision < 0) {
00100
00101 $op1 = substr($op1, 0, $decPos + $precision) . str_pad('', abs($precision), '0');
00102 }
00103
00104 if ($triggerDigit >= '5') {
00105 if ($roundPos + $decPos == -1) {
00106 return str_pad('1', $decPos + 1, '0');
00107 }
00108
00109 $roundUp = str_pad('', $length, '0');
00110 $roundUp[$decPos] = '.';
00111 $roundUp[$roundPos + $decPos] = '1';
00112
00113 if ($op1 > 0) {
00114 return self::Add($op1, $roundUp, $precision);
00115 } else {
00116 return self::Sub($op1, $roundUp, $precision);
00117 }
00118 } elseif ($precision >= 0) {
00119 return substr($op1, 0, $decPos + ($precision ? $precision + 1: 0));
00120 }
00121
00122 return (string) $op1;
00123 }
00124
00132 public static function normalize($value)
00133 {
00134 $convert = localeconv();
00135 $value = str_replace($convert['thousands_sep'], "",(string) $value);
00136 $value = str_replace($convert['positive_sign'], "", $value);
00137 $value = str_replace($convert['decimal_point'], ".",$value);
00138 if (!empty($convert['negative_sign']) and (strpos($value, $convert['negative_sign']))) {
00139 $value = str_replace($convert['negative_sign'], "", $value);
00140 $value = "-" . $value;
00141 }
00142
00143 return $value;
00144 }
00145
00153 public static function localize($value)
00154 {
00155 $convert = localeconv();
00156 $value = str_replace(".", $convert['decimal_point'], (string) $value);
00157 if (!empty($convert['negative_sign']) and (strpos($value, "-"))) {
00158 $value = str_replace("-", $convert['negative_sign'], $value);
00159 }
00160 return $value;
00161 }
00162
00171 public static function exponent($value, $scale = null)
00172 {
00173 if (!extension_loaded('bcmath')) {
00174 return $value;
00175 }
00176
00177 $split = explode('e', $value);
00178 if (count($split) == 1) {
00179 $split = explode('E', $value);
00180 }
00181
00182 if (count($split) > 1) {
00183 $value = bcmul($split[0], bcpow(10, $split[1], $scale), $scale);
00184 }
00185
00186 return $value;
00187 }
00188
00197 public static function Add($op1, $op2, $scale = null)
00198 {
00199 $op1 = self::exponent($op1, $scale);
00200 $op2 = self::exponent($op2, $scale);
00201
00202 return bcadd($op1, $op2, $scale);
00203 }
00204
00213 public static function Sub($op1, $op2, $scale = null)
00214 {
00215 $op1 = self::exponent($op1, $scale);
00216 $op2 = self::exponent($op2, $scale);
00217 return bcsub($op1, $op2, $scale);
00218 }
00219
00228 public static function Pow($op1, $op2, $scale = null)
00229 {
00230 $op1 = self::exponent($op1, $scale);
00231 $op2 = self::exponent($op2, $scale);
00232 return bcpow($op1, $op2, $scale);
00233 }
00234
00243 public static function Mul($op1, $op2, $scale = null)
00244 {
00245 $op1 = self::exponent($op1, $scale);
00246 $op2 = self::exponent($op2, $scale);
00247 return bcmul($op1, $op2, $scale);
00248 }
00249
00258 public static function Div($op1, $op2, $scale = null)
00259 {
00260 $op1 = self::exponent($op1, $scale);
00261 $op2 = self::exponent($op2, $scale);
00262 return bcdiv($op1, $op2, $scale);
00263 }
00264
00272 public static function Sqrt($op1, $scale = null)
00273 {
00274 $op1 = self::exponent($op1, $scale);
00275 return bcsqrt($op1, $scale);
00276 }
00277
00285 public static function Mod($op1, $op2)
00286 {
00287 $op1 = self::exponent($op1);
00288 $op2 = self::exponent($op2);
00289 return bcmod($op1, $op2);
00290 }
00291
00300 public static function Comp($op1, $op2, $scale = null)
00301 {
00302 $op1 = self::exponent($op1, $scale);
00303 $op2 = self::exponent($op2, $scale);
00304 return bccomp($op1, $op2, $scale);
00305 }
00306 }
00307
00308 if ((defined('TESTS_ZEND_LOCALE_BCMATH_ENABLED') && !TESTS_ZEND_LOCALE_BCMATH_ENABLED)
00309 || !extension_loaded('bcmath')) {
00310 require_once 'Zend/Locale/Math/PhpMath.php';
00311 Zend_Locale_Math_PhpMath::disable();
00312 }