fix calendar css, take 2. (#213)
[openemr.git] / interface / modules / zend_modules / library / Zend / Math / BigInteger / Adapter / Gmp.php
blobe29dc9c04897f1a83249d92cb761764db2687455
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Math\BigInteger\Adapter;
12 use Zend\Math\BigInteger\Exception;
14 /**
15 * GMP extension adapter
17 class Gmp implements AdapterInterface
19 /**
20 * Create string representing big integer in decimal form from arbitrary integer format
22 * @param string $operand
23 * @param int|null $base
24 * @return bool|string
26 public function init($operand, $base = null)
28 $sign = (strpos($operand, '-') === 0) ? '-' : '';
29 $operand = ltrim($operand, '-+');
31 if (null === $base) {
32 // scientific notation
33 if (preg_match('#^(?:([1-9])\.)?([0-9]+)[eE]\+?([0-9]+)$#', $operand, $m)) {
34 if (!empty($m[1])) {
35 if ($m[3] < strlen($m[2])) {
36 return false;
38 } else {
39 $m[1] = '';
41 $operand = str_pad(($m[1] . $m[2]), ($m[3] + 1), '0', STR_PAD_RIGHT);
42 } else {
43 // let GMP guess base
44 $base = 0;
48 set_error_handler(function () { /* Do nothing */}, \E_WARNING);
49 $res = gmp_init($sign . $operand, $base);
50 restore_error_handler();
51 if ($res === false) {
52 return false;
55 return gmp_strval($res);
58 /**
59 * Add two big integers
61 * @param string $leftOperand
62 * @param string $rightOperand
63 * @return string
65 public function add($leftOperand, $rightOperand)
67 $result = gmp_add($leftOperand, $rightOperand);
68 return gmp_strval($result);
71 /**
72 * Subtract two big integers
74 * @param string $leftOperand
75 * @param string $rightOperand
76 * @return string
78 public function sub($leftOperand, $rightOperand)
80 $result = gmp_sub($leftOperand, $rightOperand);
81 return gmp_strval($result);
84 /**
85 * Multiply two big integers
87 * @param string $leftOperand
88 * @param string $rightOperand
89 * @return string
91 public function mul($leftOperand, $rightOperand)
93 $result = gmp_mul($leftOperand, $rightOperand);
94 return gmp_strval($result);
97 /**
98 * Divide two big integers and return integer part result.
99 * Raises exception if the divisor is zero.
101 * @param string $leftOperand
102 * @param string $rightOperand
103 * @return string|null
104 * @throws Exception\DivisionByZeroException
106 public function div($leftOperand, $rightOperand)
108 if ($rightOperand == 0) {
109 throw new Exception\DivisionByZeroException(
110 "Division by zero; divisor = {$rightOperand}"
114 $result = gmp_div_q($leftOperand, $rightOperand);
115 return gmp_strval($result);
119 * Raise a big integers to another
121 * @param string $operand
122 * @param string $exp
123 * @return string
125 public function pow($operand, $exp)
127 $result = gmp_pow($operand, $exp);
128 return gmp_strval($result);
132 * Get the square root of a big integer
134 * @param string $operand
135 * @return string
137 public function sqrt($operand)
139 $result = gmp_sqrt($operand);
140 return gmp_strval($result);
144 * Get absolute value of a big integer
146 * @param string $operand
147 * @return string
149 public function abs($operand)
151 $result = gmp_abs($operand);
152 return gmp_strval($result);
156 * Get modulus of a big integer
158 * @param string $leftOperand
159 * @param string $modulus
160 * @return string
162 public function mod($leftOperand, $modulus)
164 $result = gmp_mod($leftOperand, $modulus);
165 return gmp_strval($result);
169 * Raise a big integer to another, reduced by a specified modulus
171 * @param string $leftOperand
172 * @param string $rightOperand
173 * @param string $modulus
174 * @return string
176 public function powmod($leftOperand, $rightOperand, $modulus)
178 $result = gmp_powm($leftOperand, $rightOperand, $modulus);
179 return gmp_strval($result);
183 * Compare two big integers and returns result as an integer where
184 * Returns < 0 if leftOperand is less than rightOperand;
185 * > 0 if leftOperand is greater than rightOperand, and 0 if they are equal.
187 * @param string $leftOperand
188 * @param string $rightOperand
189 * @return int
191 public function comp($leftOperand, $rightOperand)
193 return gmp_cmp($leftOperand, $rightOperand);
197 * Convert big integer into it's binary number representation
199 * @param string $int
200 * @param bool $twoc return in twos' complement form
201 * @return string
203 public function intToBin($int, $twoc = false)
205 $nb = chr(0);
206 $isNegative = (strpos($int, '-') === 0);
207 $int = ltrim($int, '+-0');
209 if (empty($int)) {
210 return $nb;
213 if ($isNegative && $twoc) {
214 $int = gmp_sub($int, '1');
217 $hex = gmp_strval($int, 16);
218 if (strlen($hex) & 1) {
219 $hex = '0' . $hex;
222 $bytes = pack('H*', $hex);
223 $bytes = ltrim($bytes, $nb);
225 if ($twoc) {
226 if (ord($bytes[0]) & 0x80) {
227 $bytes = $nb . $bytes;
229 return $isNegative ? ~$bytes : $bytes;
232 return $bytes;
236 * Convert binary number into big integer
238 * @param string $bytes
239 * @param bool $twoc whether binary number is in twos' complement form
240 * @return string
242 public function binToInt($bytes, $twoc = false)
244 $isNegative = ((ord($bytes[0]) & 0x80) && $twoc);
246 $sign = '';
247 if ($isNegative) {
248 $bytes = ~$bytes;
249 $sign = '-';
252 $result = gmp_init($sign . bin2hex($bytes), 16);
254 if ($isNegative) {
255 $result = gmp_sub($result, '1');
258 return gmp_strval($result);
262 * Base conversion. Bases 2..62 are supported
264 * @param string $operand
265 * @param int $fromBase
266 * @param int $toBase
267 * @return string
268 * @throws Exception\InvalidArgumentException
270 public function baseConvert($operand, $fromBase, $toBase = 10)
272 if ($fromBase == $toBase) {
273 return $operand;
276 if ($fromBase < 2 || $fromBase > 62) {
277 throw new Exception\InvalidArgumentException(
278 "Unsupported base: {$fromBase}, should be 2..62"
281 if ($toBase < 2 || $toBase > 62) {
282 throw new Exception\InvalidArgumentException(
283 "Unsupported base: {$toBase}, should be 2..62"
287 if ($fromBase <= 36 && $toBase <= 36) {
288 return gmp_strval(gmp_init($operand, $fromBase), $toBase);
291 $sign = (strpos($operand, '-') === 0) ? '-' : '';
292 $operand = ltrim($operand, '-+');
294 $chars = self::BASE62_ALPHABET;
296 // convert operand to decimal
297 if ($fromBase !== 10) {
298 $decimal = '0';
299 for ($i = 0, $len = strlen($operand); $i < $len; $i++) {
300 $decimal = gmp_mul($decimal, $fromBase);
301 $decimal = gmp_add($decimal, strpos($chars, $operand[$i]));
303 } else {
304 $decimal = gmp_init($operand);
307 if ($toBase == 10) {
308 return gmp_strval($decimal);
311 // convert decimal to base
312 $result = '';
313 do {
314 list($decimal, $remainder) = gmp_div_qr($decimal, $toBase);
315 $pos = gmp_strval($remainder);
316 $result = $chars[$pos] . $result;
317 } while (gmp_cmp($decimal, '0'));
319 return $sign . $result;