PageRenderTime 24ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Zend/Locale/Math.php

https://bitbucket.org/blackriver/openx
PHP | 154 lines | 89 code | 9 blank | 56 comment | 16 complexity | 7db4e14eea2ecf6b67566601d029a847 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-2008 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 8672 2008-03-07 21:20:42Z thomas $
  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-2008 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 = 'bcadd';
  37. public static $sub = 'bcsub';
  38. public static $pow = 'bcpow';
  39. public static $mul = 'bcmul';
  40. public static $div = 'bcdiv';
  41. public static $comp = 'bccomp';
  42. public static $sqrt = 'bcsqrt';
  43. public static $mod = 'bcmod';
  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. return self::normalize(round($op1, $precision));
  63. }
  64. $op1 = trim(self::normalize($op1));
  65. $length = strlen($op1);
  66. if (($decPos = strpos($op1, '.')) === false) {
  67. $op1 .= '.0';
  68. $decPos = $length;
  69. $length += 2;
  70. }
  71. if ($precision < 0 && abs($precision) > $decPos) {
  72. return '0';
  73. }
  74. $digitsBeforeDot = $length - ($decPos + 1);
  75. if ($precision >= ($length - ($decPos + 1))) {
  76. return $op1;
  77. }
  78. if ($precision === 0) {
  79. $triggerPos = 1;
  80. $roundPos = -1;
  81. } elseif ($precision > 0) {
  82. $triggerPos = $precision + 1;
  83. $roundPos = $precision;
  84. } else {
  85. $triggerPos = $precision;
  86. $roundPos = $precision -1;
  87. }
  88. $triggerDigit = $op1[$triggerPos + $decPos];
  89. if ($precision < 0) {
  90. // zero fill digits to the left of the decimal place
  91. $op1 = substr($op1, 0, $decPos + $precision) . str_pad('', abs($precision), '0');
  92. }
  93. if ($triggerDigit >= '5') {
  94. if ($roundPos + $decPos == -1) {
  95. return str_pad('1', $decPos + 1, '0');
  96. }
  97. $roundUp = str_pad('', $length, '0');
  98. $roundUp[$decPos] = '.';
  99. $roundUp[$roundPos + $decPos] = '1';
  100. return bcadd($op1, $roundUp, $precision);
  101. } elseif ($precision >= 0) {
  102. return substr($op1, 0, $decPos + ($precision ? $precision + 1: 0));
  103. }
  104. return (string) $op1;
  105. }
  106. /**
  107. * Normalizes an input to standard english notation
  108. * Fixes a problem of BCMath with setLocale which is PHP related
  109. *
  110. * @param integer $value Value to normalize
  111. * @return string Normalized string without BCMath problems
  112. */
  113. public static function normalize($value)
  114. {
  115. $convert = localeconv();
  116. $value = str_replace($convert['thousands_sep'], "",(string) $value);
  117. $value = str_replace($convert['positive_sign'], "", $value);
  118. $value = str_replace($convert['decimal_point'], ".",$value);
  119. if (!empty($convert['negative_sign']) and (strpos($value, $convert['negative_sign']))) {
  120. $value = str_replace($convert['negative_sign'], "", $value);
  121. $value = "-" . $value;
  122. }
  123. return $value;
  124. }
  125. /**
  126. * Localizes an input from standard english notation
  127. * Fixes a problem of BCMath with setLocale which is PHP related
  128. *
  129. * @param integer $value Value to normalize
  130. * @return string Normalized string without BCMath problems
  131. */
  132. public static function localize($value)
  133. {
  134. $convert = localeconv();
  135. $value = str_replace(".", $convert['decimal_point'], (string) $value);
  136. if (!empty($convert['negative_sign']) and (strpos($value, "-"))) {
  137. $value = str_replace("-", $convert['negative_sign'], $value);
  138. }
  139. return $value;
  140. }
  141. }
  142. if ((defined('TESTS_ZEND_LOCALE_BCMATH_ENABLED') && !TESTS_ZEND_LOCALE_BCMATH_ENABLED)
  143. || !extension_loaded('bcmath')) {
  144. require_once 'Zend/Locale/Math/PhpMath.php';
  145. }