00001 <?php
00034 class Zend_Locale_Math_PhpMath extends Zend_Locale_Math
00035 {
00036 public static function disable()
00037 {
00038 self::$_bcmathDisabled = true;
00039 self::$add = array('Zend_Locale_Math_PhpMath', 'Add');
00040 self::$sub = array('Zend_Locale_Math_PhpMath', 'Sub');
00041 self::$pow = array('Zend_Locale_Math_PhpMath', 'Pow');
00042 self::$mul = array('Zend_Locale_Math_PhpMath', 'Mul');
00043 self::$div = array('Zend_Locale_Math_PhpMath', 'Div');
00044 self::$comp = array('Zend_Locale_Math_PhpMath', 'Comp');
00045 self::$sqrt = array('Zend_Locale_Math_PhpMath', 'Sqrt');
00046 self::$mod = array('Zend_Locale_Math_PhpMath', 'Mod');
00047 self::$scale = array('Zend_Locale_Math_PhpMath', 'Scale');
00048
00049 self::$defaultScale = 0;
00050 self::$defaultPrecision = 1;
00051 }
00052
00053 public static $defaultScale;
00054 public static $defaultPrecision;
00055
00056
00057 public static function Add($op1, $op2, $scale = null)
00058 {
00059 if ($scale === null) {
00060 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00061 $precision = Zend_Locale_Math_PhpMath::$defaultPrecision;
00062 } else {
00063 $precision = pow(10, -$scale);
00064 }
00065
00066 if (empty($op1)) {
00067 $op1 = 0;
00068 }
00069 $op1 = self::normalize($op1);
00070 $op2 = self::normalize($op2);
00071 $result = $op1 + $op2;
00072 if (is_infinite($result) or (abs($result - $op2 - $op1) > $precision)) {
00073 require_once 'Zend/Locale/Math/Exception.php';
00074 throw new Zend_Locale_Math_Exception("addition overflow: $op1 + $op2 != $result", $op1, $op2, $result);
00075 }
00076
00077 return self::round(self::normalize($result), $scale);
00078 }
00079
00080 public static function Sub($op1, $op2, $scale = null)
00081 {
00082 if ($scale === null) {
00083 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00084 $precision = Zend_Locale_Math_PhpMath::$defaultPrecision;
00085 } else {
00086 $precision = pow(10, -$scale);
00087 }
00088
00089 if (empty($op1)) {
00090 $op1 = 0;
00091 }
00092 $op1 = self::normalize($op1);
00093 $op2 = self::normalize($op2);
00094 $result = $op1 - $op2;
00095 if (is_infinite($result) or (abs($result + $op2 - $op1) > $precision)) {
00096 require_once 'Zend/Locale/Math/Exception.php';
00097 throw new Zend_Locale_Math_Exception("subtraction overflow: $op1 - $op2 != $result", $op1, $op2, $result);
00098 }
00099
00100 return self::round(self::normalize($result), $scale);
00101 }
00102
00103 public static function Pow($op1, $op2, $scale = null)
00104 {
00105 if ($scale === null) {
00106 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00107 }
00108
00109 $op1 = self::normalize($op1);
00110 $op2 = self::normalize($op2);
00111
00112
00113
00114 $op2 = ($op2 > 0) ? floor($op2) : ceil($op2);
00115
00116 $result = pow($op1, $op2);
00117 if (is_infinite($result) or is_nan($result)) {
00118 require_once 'Zend/Locale/Math/Exception.php';
00119 throw new Zend_Locale_Math_Exception("power overflow: $op1 ^ $op2", $op1, $op2, $result);
00120 }
00121
00122 return self::round(self::normalize($result), $scale);
00123 }
00124
00125 public static function Mul($op1, $op2, $scale = null)
00126 {
00127 if ($scale === null) {
00128 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00129 }
00130
00131 if (empty($op1)) {
00132 $op1 = 0;
00133 }
00134 $op1 = self::normalize($op1);
00135 $op2 = self::normalize($op2);
00136 $result = $op1 * $op2;
00137 if (is_infinite($result) or is_nan($result)) {
00138 require_once 'Zend/Locale/Math/Exception.php';
00139 throw new Zend_Locale_Math_Exception("multiplication overflow: $op1 * $op2 != $result", $op1, $op2, $result);
00140 }
00141
00142 return self::round(self::normalize($result), $scale);
00143 }
00144
00145 public static function Div($op1, $op2, $scale = null)
00146 {
00147 if ($scale === null) {
00148 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00149 }
00150
00151 if (empty($op2)) {
00152 require_once 'Zend/Locale/Math/Exception.php';
00153 throw new Zend_Locale_Math_Exception("can not divide by zero", $op1, $op2, null);
00154 }
00155 if (empty($op1)) {
00156 $op1 = 0;
00157 }
00158 $op1 = self::normalize($op1);
00159 $op2 = self::normalize($op2);
00160 $result = $op1 / $op2;
00161 if (is_infinite($result) or is_nan($result)) {
00162 require_once 'Zend/Locale/Math/Exception.php';
00163 throw new Zend_Locale_Math_Exception("division overflow: $op1 / $op2 != $result", $op1, $op2, $result);
00164 }
00165
00166 return self::round(self::normalize($result), $scale);
00167 }
00168
00169 public static function Sqrt($op1, $scale = null)
00170 {
00171 if ($scale === null) {
00172 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00173 }
00174
00175 if (empty($op1)) {
00176 $op1 = 0;
00177 }
00178 $op1 = self::normalize($op1);
00179 $result = sqrt($op1);
00180 if (is_nan($result)) {
00181 return NULL;
00182 }
00183
00184 return self::round(self::normalize($result), $scale);
00185 }
00186
00187 public static function Mod($op1, $op2)
00188 {
00189 if (empty($op1)) {
00190 $op1 = 0;
00191 }
00192 if (empty($op2)) {
00193 return NULL;
00194 }
00195 $op1 = self::normalize($op1);
00196 $op2 = self::normalize($op2);
00197 if ((int)$op2 == 0) {
00198 return NULL;
00199 }
00200 $result = $op1 % $op2;
00201 if (is_nan($result) or (($op1 - $result) % $op2 != 0)) {
00202 require_once 'Zend/Locale/Math/Exception.php';
00203 throw new Zend_Locale_Math_Exception("modulus calculation error: $op1 % $op2 != $result", $op1, $op2, $result);
00204 }
00205
00206 return self::normalize($result);
00207 }
00208
00209 public static function Comp($op1, $op2, $scale = null)
00210 {
00211 if ($scale === null) {
00212 $scale = Zend_Locale_Math_PhpMath::$defaultScale;
00213 }
00214
00215 if (empty($op1)) {
00216 $op1 = 0;
00217 }
00218 $op1 = self::normalize($op1);
00219 $op2 = self::normalize($op2);
00220 if ($scale <> 0) {
00221 $op1 = self::round($op1, $scale);
00222 $op2 = self::round($op2, $scale);
00223 } else {
00224 $op1 = ($op1 > 0) ? floor($op1) : ceil($op1);
00225 $op2 = ($op2 > 0) ? floor($op2) : ceil($op2);
00226 }
00227 if ($op1 > $op2) {
00228 return 1;
00229 } else if ($op1 < $op2) {
00230 return -1;
00231 }
00232 return 0;
00233 }
00234
00235 public static function Scale($scale)
00236 {
00237 if ($scale > 9) {
00238 require_once 'Zend/Locale/Math/Exception.php';
00239 throw new Zend_Locale_Math_Exception("can not scale to precision $scale", $scale, null, null);
00240 }
00241 self::$defaultScale = $scale;
00242 self::$defaultPrecision = pow(10, -$scale);
00243 return true;
00244 }
00245 }
00246
00247 Zend_Locale_Math_PhpMath::disable();