PageRenderTime 219ms CodeModel.GetById 42ms RepoModel.GetById 1ms app.codeStats 0ms

/concreteOLD/libraries/3rdparty/Zend/Locale/Math.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 355 lines | 187 code | 36 blank | 132 comment | 30 complexity | a86757f06d0d68e20d2a42432615f086 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Locale
  17. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Math.php 23775 2011-03-01 17:25:24Z ralph $
  20. */
  21. /**
  22. * Utility class for proxying math function to bcmath functions, if present,
  23. * otherwise to PHP builtin math operators, with limited detection of overflow conditions.
  24. * Sampling of PHP environments and platforms suggests that at least 80% to 90% support bcmath.
  25. * Thus, this file should be as light as possible.
  26. *
  27. * @category Zend
  28. * @package Zend_Locale
  29. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Zend_Locale_Math
  33. {
  34. // support unit testing without using bcmath functions
  35. public static $_bcmathDisabled = false;
  36. public static $add = array('Zend_Locale_Math', 'Add');
  37. public static $sub = array('Zend_Locale_Math', 'Sub');
  38. public static $pow = array('Zend_Locale_Math', 'Pow');
  39. public static $mul = array('Zend_Locale_Math', 'Mul');
  40. public static $div = array('Zend_Locale_Math', 'Div');
  41. public static $comp = array('Zend_Locale_Math', 'Comp');
  42. public static $sqrt = array('Zend_Locale_Math', 'Sqrt');
  43. public static $mod = array('Zend_Locale_Math', 'Mod');
  44. public static $scale = 'bcscale';
  45. public static function isBcmathDisabled()
  46. {
  47. return self::$_bcmathDisabled;
  48. }
  49. /**
  50. * Surprisingly, the results of this implementation of round()
  51. * prove better than the native PHP round(). For example, try:
  52. * round(639.795, 2);
  53. * round(267.835, 2);
  54. * round(0.302515, 5);
  55. * round(0.36665, 4);
  56. * then try:
  57. * Zend_Locale_Math::round('639.795', 2);
  58. */
  59. public static function round($op1, $precision = 0)
  60. {
  61. if (self::$_bcmathDisabled) {
  62. $op1 = round($op1, $precision);
  63. if (strpos((string) $op1, 'E') === false) {
  64. return self::normalize(round($op1, $precision));
  65. }
  66. }
  67. if (strpos($op1, 'E') !== false) {
  68. $op1 = self::floatalize($op1);
  69. }
  70. $op1 = trim(self::normalize($op1));
  71. $length = strlen($op1);
  72. if (($decPos = strpos($op1, '.')) === false) {
  73. $op1 .= '.0';
  74. $decPos = $length;
  75. $length += 2;
  76. }
  77. if ($precision < 0 && abs($precision) > $decPos) {
  78. return '0';
  79. }
  80. $digitsBeforeDot = $length - ($decPos + 1);
  81. if ($precision >= ($length - ($decPos + 1))) {
  82. return $op1;
  83. }
  84. if ($precision === 0) {
  85. $triggerPos = 1;
  86. $roundPos = -1;
  87. } elseif ($precision > 0) {
  88. $triggerPos = $precision + 1;
  89. $roundPos = $precision;
  90. } else {
  91. $triggerPos = $precision;
  92. $roundPos = $precision -1;
  93. }
  94. $triggerDigit = $op1[$triggerPos + $decPos];
  95. if ($precision < 0) {
  96. // zero fill digits to the left of the decimal place
  97. $op1 = substr($op1, 0, $decPos + $precision) . str_pad('', abs($precision), '0');
  98. }
  99. if ($triggerDigit >= '5') {
  100. if ($roundPos + $decPos == -1) {
  101. return str_pad('1', $decPos + 1, '0');
  102. }
  103. $roundUp = str_pad('', $length, '0');
  104. $roundUp[$decPos] = '.';
  105. $roundUp[$roundPos + $decPos] = '1';
  106. if ($op1 > 0) {
  107. if (self::$_bcmathDisabled) {
  108. return Zend_Locale_Math_PhpMath::Add($op1, $roundUp, $precision);
  109. }
  110. return self::Add($op1, $roundUp, $precision);
  111. } else {
  112. if (self::$_bcmathDisabled) {
  113. return Zend_Locale_Math_PhpMath::Sub($op1, $roundUp, $precision);
  114. }
  115. return self::Sub($op1, $roundUp, $precision);
  116. }
  117. } elseif ($precision >= 0) {
  118. return substr($op1, 0, $decPos + ($precision ? $precision + 1: 0));
  119. }
  120. return (string) $op1;
  121. }
  122. /**
  123. * Convert a scientific notation to float
  124. * Additionally fixed a problem with PHP <= 5.2.x with big integers
  125. *
  126. * @param string $value
  127. */
  128. public static function floatalize($value)
  129. {
  130. $value = strtoupper($value);
  131. if (strpos($value, 'E') === false) {
  132. return $value;
  133. }
  134. $number = substr($value, 0, strpos($value, 'E'));
  135. if (strpos($number, '.') !== false) {
  136. $post = strlen(substr($number, strpos($number, '.') + 1));
  137. $mantis = substr($value, strpos($value, 'E') + 1);
  138. if ($mantis < 0) {
  139. $post += abs((int) $mantis);
  140. }
  141. $value = number_format($value, $post, '.', '');
  142. } else {
  143. $value = number_format($value, 0, '.', '');
  144. }
  145. return $value;
  146. }
  147. /**
  148. * Normalizes an input to standard english notation
  149. * Fixes a problem of BCMath with setLocale which is PHP related
  150. *
  151. * @param integer $value Value to normalize
  152. * @return string Normalized string without BCMath problems
  153. */
  154. public static function normalize($value)
  155. {
  156. $convert = localeconv();
  157. $value = str_replace($convert['thousands_sep'], "",(string) $value);
  158. $value = str_replace($convert['positive_sign'], "", $value);
  159. $value = str_replace($convert['decimal_point'], ".",$value);
  160. if (!empty($convert['negative_sign']) and (strpos($value, $convert['negative_sign']))) {
  161. $value = str_replace($convert['negative_sign'], "", $value);
  162. $value = "-" . $value;
  163. }
  164. return $value;
  165. }
  166. /**
  167. * Localizes an input from standard english notation
  168. * Fixes a problem of BCMath with setLocale which is PHP related
  169. *
  170. * @param integer $value Value to normalize
  171. * @return string Normalized string without BCMath problems
  172. */
  173. public static function localize($value)
  174. {
  175. $convert = localeconv();
  176. $value = str_replace(".", $convert['decimal_point'], (string) $value);
  177. if (!empty($convert['negative_sign']) and (strpos($value, "-"))) {
  178. $value = str_replace("-", $convert['negative_sign'], $value);
  179. }
  180. return $value;
  181. }
  182. /**
  183. * Changes exponential numbers to plain string numbers
  184. * Fixes a problem of BCMath with numbers containing exponents
  185. *
  186. * @param integer $value Value to erase the exponent
  187. * @param integer $scale (Optional) Scale to use
  188. * @return string
  189. */
  190. public static function exponent($value, $scale = null)
  191. {
  192. if (!extension_loaded('bcmath')) {
  193. return $value;
  194. }
  195. $split = explode('e', $value);
  196. if (count($split) == 1) {
  197. $split = explode('E', $value);
  198. }
  199. if (count($split) > 1) {
  200. $value = bcmul($split[0], bcpow(10, $split[1], $scale), $scale);
  201. }
  202. return $value;
  203. }
  204. /**
  205. * BCAdd - fixes a problem of BCMath and exponential numbers
  206. *
  207. * @param string $op1
  208. * @param string $op2
  209. * @param integer $scale
  210. * @return string
  211. */
  212. public static function Add($op1, $op2, $scale = null)
  213. {
  214. $op1 = self::exponent($op1, $scale);
  215. $op2 = self::exponent($op2, $scale);
  216. return bcadd($op1, $op2, $scale);
  217. }
  218. /**
  219. * BCSub - fixes a problem of BCMath and exponential numbers
  220. *
  221. * @param string $op1
  222. * @param string $op2
  223. * @param integer $scale
  224. * @return string
  225. */
  226. public static function Sub($op1, $op2, $scale = null)
  227. {
  228. $op1 = self::exponent($op1, $scale);
  229. $op2 = self::exponent($op2, $scale);
  230. return bcsub($op1, $op2, $scale);
  231. }
  232. /**
  233. * BCPow - fixes a problem of BCMath and exponential numbers
  234. *
  235. * @param string $op1
  236. * @param string $op2
  237. * @param integer $scale
  238. * @return string
  239. */
  240. public static function Pow($op1, $op2, $scale = null)
  241. {
  242. $op1 = self::exponent($op1, $scale);
  243. $op2 = self::exponent($op2, $scale);
  244. return bcpow($op1, $op2, $scale);
  245. }
  246. /**
  247. * BCMul - fixes a problem of BCMath and exponential numbers
  248. *
  249. * @param string $op1
  250. * @param string $op2
  251. * @param integer $scale
  252. * @return string
  253. */
  254. public static function Mul($op1, $op2, $scale = null)
  255. {
  256. $op1 = self::exponent($op1, $scale);
  257. $op2 = self::exponent($op2, $scale);
  258. return bcmul($op1, $op2, $scale);
  259. }
  260. /**
  261. * BCDiv - fixes a problem of BCMath and exponential numbers
  262. *
  263. * @param string $op1
  264. * @param string $op2
  265. * @param integer $scale
  266. * @return string
  267. */
  268. public static function Div($op1, $op2, $scale = null)
  269. {
  270. $op1 = self::exponent($op1, $scale);
  271. $op2 = self::exponent($op2, $scale);
  272. return bcdiv($op1, $op2, $scale);
  273. }
  274. /**
  275. * BCSqrt - fixes a problem of BCMath and exponential numbers
  276. *
  277. * @param string $op1
  278. * @param integer $scale
  279. * @return string
  280. */
  281. public static function Sqrt($op1, $scale = null)
  282. {
  283. $op1 = self::exponent($op1, $scale);
  284. return bcsqrt($op1, $scale);
  285. }
  286. /**
  287. * BCMod - fixes a problem of BCMath and exponential numbers
  288. *
  289. * @param string $op1
  290. * @param string $op2
  291. * @return string
  292. */
  293. public static function Mod($op1, $op2)
  294. {
  295. $op1 = self::exponent($op1);
  296. $op2 = self::exponent($op2);
  297. return bcmod($op1, $op2);
  298. }
  299. /**
  300. * BCComp - fixes a problem of BCMath and exponential numbers
  301. *
  302. * @param string $op1
  303. * @param string $op2
  304. * @param integer $scale
  305. * @return string
  306. */
  307. public static function Comp($op1, $op2, $scale = null)
  308. {
  309. $op1 = self::exponent($op1, $scale);
  310. $op2 = self::exponent($op2, $scale);
  311. return bccomp($op1, $op2, $scale);
  312. }
  313. }
  314. if (!extension_loaded('bcmath')
  315. || (defined('TESTS_ZEND_LOCALE_BCMATH_ENABLED') && !TESTS_ZEND_LOCALE_BCMATH_ENABLED)
  316. ) {
  317. require_once 'Zend/Locale/Math/PhpMath.php';
  318. Zend_Locale_Math_PhpMath::disable();
  319. }