$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 Zend_Locale_Math_PhpMath::Add($op1, $roundUp, $precision); } return self::Add($op1, $roundUp, $precision); } else { if (self::$_bcmathDisabled) { return 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; } /** * Convert a scientific notation to float * Additionally fixed a problem with PHP <= 5.2.x with big integers * * @param string $value */ public static function floatalize($value) { $value = strtoupper($value); if (strpos($value, 'E') === false) { return $value; } $number = substr($value, 0, strpos($value, 'E')); if (strpos($number, '.') !== false) { $post = strlen(substr($number, strpos($number, '.') + 1)); $mantis = substr($value, strpos($value, 'E') + 1); if ($mantis < 0) { $post += abs((int) $mantis); } $value = number_format($value, $post, '.', ''); } else { $value = number_format($value, 0, '.', ''); } return $value; } /** * Normalizes an input to standard english notation * Fixes a problem of BCMath with setLocale which is PHP related * * @param integer $value Value to normalize * @return string Normalized string without BCMath problems */ public static function normalize($value) { $convert = localeconv(); $value = str_replace($convert['thousands_sep'], "",(string) $value); $value = str_replace($convert['positive_sign'], "", $value); $value = str_replace($convert['decimal_point'], ".",$value); if (!empty($convert['negative_sign']) and (strpos($value, $convert['negative_sign']))) { $value = str_replace($convert['negative_sign'], "", $value); $value = "-" . $value; } return $value; } /** * Localizes an input from standard english notation * Fixes a problem of BCMath with setLocale which is PHP related * * @param integer $value Value to normalize * @return string Normalized string without BCMath problems */ public static function localize($value) { $convert = localeconv(); $value = str_replace(".", $convert['decimal_point'], (string) $value); if (!empty($convert['negative_sign']) and (strpos($value, "-"))) { $value = str_replace("-", $convert['negative_sign'], $value); } return $value; } /** * Changes exponential numbers to plain string numbers * Fixes a problem of BCMath with numbers containing exponents * * @param integer $value Value to erase the exponent * @param integer $scale (Optional) Scale to use * @return string */ public static function exponent($value, $scale = null) { if (!extension_loaded('bcmath')) { return $value; } $split = explode('e', $value); if (count($split) == 1) { $split = explode('E', $value); } if (count($split) > 1) { $value = bcmul($split[0], bcpow(10, $split[1], $scale), $scale); } return $value; } /** * BCAdd - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @param integer $scale * @return string */ public static function Add($op1, $op2, $scale = null) { $op1 = self::exponent($op1, $scale); $op2 = self::exponent($op2, $scale); return bcadd($op1, $op2, $scale); } /** * BCSub - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @param integer $scale * @return string */ public static function Sub($op1, $op2, $scale = null) { $op1 = self::exponent($op1, $scale); $op2 = self::exponent($op2, $scale); return bcsub($op1, $op2, $scale); } /** * BCPow - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @param integer $scale * @return string */ public static function Pow($op1, $op2, $scale = null) { $op1 = self::exponent($op1, $scale); $op2 = self::exponent($op2, $scale); return bcpow($op1, $op2, $scale); } /** * BCMul - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @param integer $scale * @return string */ public static function Mul($op1, $op2, $scale = null) { $op1 = self::exponent($op1, $scale); $op2 = self::exponent($op2, $scale); return bcmul($op1, $op2, $scale); } /** * BCDiv - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @param integer $scale * @return string */ public static function Div($op1, $op2, $scale = null) { $op1 = self::exponent($op1, $scale); $op2 = self::exponent($op2, $scale); return bcdiv($op1, $op2, $scale); } /** * BCSqrt - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param integer $scale * @return string */ public static function Sqrt($op1, $scale = null) { $op1 = self::exponent($op1, $scale); return bcsqrt($op1, $scale); } /** * BCMod - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @return string */ public static function Mod($op1, $op2) { $op1 = self::exponent($op1); $op2 = self::exponent($op2); return bcmod($op1, $op2); } /** * BCComp - fixes a problem of BCMath and exponential numbers * * @param string $op1 * @param string $op2 * @param integer $scale * @return string */ public static function Comp($op1, $op2, $scale = null) { $op1 = self::exponent($op1, $scale); $op2 = self::exponent($op2, $scale); return bccomp($op1, $op2, $scale); } } if (!extension_loaded('bcmath') || (defined('TESTS_ZEND_LOCALE_BCMATH_ENABLED') && !TESTS_ZEND_LOCALE_BCMATH_ENABLED) ) { require_once 'Zend/Locale/Math/PhpMath.php'; Zend_Locale_Math_PhpMath::disable(); }