/src/classes/XLite/Logic/Math.php

https://github.com/Koc/core · PHP · 276 lines · 86 code · 25 blank · 165 comment · 5 complexity · cf53273de1b7301f4b51518d39f874d7 MD5 · raw file

  1. <?php
  2. // vim: set ts=4 sw=4 sts=4 et:
  3. /**
  4. * LiteCommerce
  5. *
  6. * NOTICE OF LICENSE
  7. *
  8. * This source file is subject to the Open Software License (OSL 3.0)
  9. * that is bundled with this package in the file LICENSE.txt.
  10. * It is also available through the world-wide-web at this URL:
  11. * http://opensource.org/licenses/osl-3.0.php
  12. * If you did not receive a copy of the license and are unable to
  13. * obtain it through the world-wide-web, please send an email
  14. * to licensing@litecommerce.com so we can send you a copy immediately.
  15. *
  16. * PHP version 5.3.0
  17. *
  18. * @category LiteCommerce
  19. * @author Creative Development LLC <info@cdev.ru>
  20. * @copyright Copyright (c) 2011 Creative Development LLC <info@cdev.ru>. All rights reserved
  21. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  22. * @link http://www.litecommerce.com/
  23. * @see ____file_see____
  24. * @since 1.0.0
  25. */
  26. namespace XLite\Logic;
  27. /**
  28. * Mathematic
  29. *
  30. * @see ____class_see____
  31. * @since 1.0.0
  32. */
  33. class Math extends \XLite\Logic\ALogic
  34. {
  35. /**
  36. * Storage precision
  37. */
  38. const STORE_PRECISION = 4;
  39. // {{{ Round
  40. /**
  41. * Round
  42. *
  43. * @param float $value Value
  44. * @param integer $precision Precision OPTIONAL
  45. *
  46. * @return float|integer
  47. * @see ____func_see____
  48. * @since 1.0.0
  49. */
  50. public function round($value, $precision = 0)
  51. {
  52. return $this->roundMath($value, $precision);
  53. }
  54. /**
  55. * Round by currency
  56. *
  57. * @param float $value Value
  58. * @param \XLite\Model\Currency $currency Currency
  59. *
  60. * @return float
  61. * @see ____func_see____
  62. * @since 1.0.0
  63. */
  64. public function roundByCurrency($value, \XLite\Model\Currency $currency)
  65. {
  66. return $this->round($value, $currency->getE());
  67. }
  68. /**
  69. * Round and format by currency
  70. *
  71. * @param float $value Value
  72. * @param \XLite\Model\Currency $currency Currency
  73. *
  74. * @return string
  75. * @see ____func_see____
  76. * @since 1.0.0
  77. */
  78. public function formatValue($value, \XLite\Model\Currency $currency)
  79. {
  80. $config = \XLite\Core\Config::getInstance();
  81. return number_format(
  82. $this->roundByCurrency($value, $currency),
  83. $currency->getE(),
  84. $config->General->decimal_delim,
  85. $config->General->thousand_delim
  86. );
  87. }
  88. /**
  89. * Round up
  90. *
  91. * @param float $value Value
  92. * @param integer $precision Precision OPTIONAL
  93. *
  94. * @return float|integer
  95. * @see ____func_see____
  96. * @since 1.0.0
  97. */
  98. public function roundUp($value, $precision = 0)
  99. {
  100. $multi = pow(10, $precision);
  101. return ceil($value * $multi) / $multi;
  102. }
  103. /**
  104. * Round down
  105. *
  106. * @param float $value Value
  107. * @param integer $precision Precision OPTIONAL
  108. *
  109. * @return float|integer
  110. * @see ____func_see____
  111. * @since 1.0.0
  112. */
  113. public function roundDown($value, $precision = 0)
  114. {
  115. $multi = pow(10, $precision);
  116. return floor($value * $multi) / $multi;
  117. }
  118. /**
  119. * Round up (ceiling)
  120. *
  121. * @param float $value Value
  122. * @param integer $precision Precision OPTIONAL
  123. *
  124. * @return float|integer
  125. * @see ____func_see____
  126. * @since 1.0.0
  127. */
  128. public function roundCeil($value, $precision = 0)
  129. {
  130. return 0 > $value
  131. ? $this->roundDown($value, $precision)
  132. : $this->roundUp($value, $precision);
  133. }
  134. /**
  135. * Round down (floor)
  136. *
  137. * @param float $value Value
  138. * @param integer $precision Precision OPTIONAL
  139. *
  140. * @return float|integer
  141. * @see ____func_see____
  142. * @since 1.0.0
  143. */
  144. public function roundFloor($value, $precision = 0)
  145. {
  146. return 0 > $value
  147. ? $this->roundUp($value, $precision)
  148. : $this->roundDown($value, $precision);
  149. }
  150. /**
  151. * Round (half up)
  152. *
  153. * @param float $value Value
  154. * @param integer $precision Precision OPTIONAL
  155. *
  156. * @return float|integer
  157. * @see ____func_see____
  158. * @since 1.0.0
  159. */
  160. public function roundHalfUp($value, $precision = 0)
  161. {
  162. return $this->isRoundHalf($value, $precision)
  163. ? $this->roundCeil($value, $precision)
  164. : $this->roundMath($value, $precision);
  165. }
  166. /**
  167. * Round (half down)
  168. *
  169. * @param float $value Value
  170. * @param integer $precision Precision OPTIONAL
  171. *
  172. * @return float|integer
  173. * @see ____func_see____
  174. * @since 1.0.0
  175. */
  176. public function roundHalfDown($value, $precision = 0)
  177. {
  178. return $this->isRoundHalf($value, $precision)
  179. ? $this->roundFloor($value, $precision)
  180. : $this->roundMath($value, $precision);
  181. }
  182. /**
  183. * Round (half even)
  184. *
  185. * @param float $value Value
  186. * @param integer $precision Precision OPTIONAL
  187. *
  188. * @return float|integer
  189. * @see ____func_see____
  190. * @since 1.0.0
  191. */
  192. public function roundHalfEven($value, $precision = 0)
  193. {
  194. if ($this->isRoundHalf($value, $precision)) {
  195. $result = $this->isRoundEven($value, $precision)
  196. ? $this->roundFloor($value, $precision)
  197. : $this->roundCeil($value, $precision);
  198. } else {
  199. $result = $this->roundMath($value, $precision);
  200. }
  201. return $result;
  202. }
  203. /**
  204. * Round (standard)
  205. *
  206. * @param float $value Value
  207. * @param integer $precision Precision OPTIONAL
  208. *
  209. * @return float|integer
  210. * @see ____func_see____
  211. * @since 1.0.0
  212. */
  213. public function roundMath($value, $precision = 0)
  214. {
  215. return round($value, $precision);
  216. }
  217. /**
  218. * Check - value is half-based or not
  219. *
  220. * @param float $value Value
  221. * @param integer $precision Precision
  222. *
  223. * @return boolean
  224. * @see ____func_see____
  225. * @since 1.0.0
  226. */
  227. protected function isRoundHalf($value, $precision)
  228. {
  229. $result = false;
  230. $value -= floor($value);
  231. if (0 != $value) {
  232. $result = (bool)preg_match('/^50*$/Ss', substr($value, $precision + 2));
  233. }
  234. return $result;
  235. }
  236. /**
  237. * Check - value is even or not
  238. *
  239. * @param float $value Value
  240. * @param integer $precision Precision
  241. *
  242. * @return boolean
  243. * @see ____func_see____
  244. * @since 1.0.0
  245. */
  246. protected function isRoundEven($value, $precision)
  247. {
  248. return 0 == floor($value * pow(10, $precision)) % 2;
  249. }
  250. // }}}
  251. }