1: <?php
2: namespace NGS;
3:
4: require_once(__DIR__.'/Utils.php');
5:
6: use NGS\Utils;
7:
8: class BigInt
9: {
10: private $value;
11:
12: public static function from($value)
13: {
14: if (null === $value) {
15: throw new \InvalidArgumentException('BigInt value cannot be null');
16: }
17: elseif (is_string($value)) {
18: if (!preg_match('/^[-+]?\\d+$/u', $value)) {
19: throw new \InvalidArgumentException('Invalid characters in BigInt constructor string: '.$value);
20: }
21:
22: return new BigInt($value);
23: }
24: elseif (is_object($value) && ('NGS\BigInt' === get_class($value))) {
25: return $value;
26: }
27: elseif (is_int($value))
28: {
29: return new BigInt((string) $value);
30: }
31:
32: throw new \InvalidArgumentException('BigInt could not be constructed from type "'.Utils::getType($value).'"');
33: }
34:
35: private function __construct($value)
36: {
37: $this->value = $value;
38: }
39:
40: public static function toArray(array $items)
41: {
42: try {
43: foreach ($items as $key => &$val) {
44: if($val === null) {
45: throw new \InvalidArgumentException('Null value found in provided array');
46: }
47: if(!$val instanceof \NGS\BigInt) {
48: $val = self::from($val);
49: }
50: }
51: }
52: catch(\Exception $e) {
53: throw new \InvalidArgumentException('Element at index '.$key.' could not be converted to BigInt!', 42, $e);
54: }
55: return $items;
56: }
57:
58:
59: private function _add(BigInt $other)
60: {
61: return new BigInt(bcadd($this->value, $other->value, 0));
62: }
63:
64: public function add($other)
65: {
66: return $this->_add(self::from($other));
67: }
68:
69: private function _sub(BigInt $other)
70: {
71: return new BigInt(bcsub($this->value, $other->value, 0));
72: }
73:
74: public function sub($other)
75: {
76: return $this->_sub(self::from($other));
77: }
78:
79:
80:
81: private function _comp(BigInt $other)
82: {
83: return bccomp($this->value, $other->value, 0);
84: }
85:
86: public function comp($other)
87: {
88: return $this->_comp(self::from($other));
89: }
90:
91: private function _gt(BigInt $other)
92: {
93: return $this->comp($other) > 0;
94: }
95:
96: public function gt($other)
97: {
98: return $this->_gt(self::from($other));
99: }
100:
101: private function _gte(BigInt $other)
102: {
103: return $this->comp($other) >= 0;
104: }
105:
106: public function gte($other)
107: {
108: return $this->_gte(self::from($other));
109: }
110:
111: private function _lt(BigInt $other)
112: {
113: return $this->comp($other) < 0;
114: }
115:
116: public function lt($other)
117: {
118: return $this->_lt(self::from($other));
119: }
120:
121: private function _lte(BigInt $other)
122: {
123: return $this->comp($other) <= 0;
124: }
125:
126: public function lte($other)
127: {
128: return $this->_lte(self::from($other));
129: }
130:
131:
132:
133: private function _mul(BigInt $other)
134: {
135: return new BigInt(bcmul($this->value, $other->value, 0));
136: }
137:
138: public function mul($other)
139: {
140: return $this->_mul(self::from($other));
141: }
142:
143: private function _div(BigInt $other)
144: {
145: return new BigInt(bcdiv($this->value, $other->value, 0));
146: }
147:
148: public function div($other)
149: {
150: return $this->_div(self::from($other));
151: }
152:
153: private function _mod(BigInt $other) {
154: return new BigInt(bcmod($this->value, $other->value, 0));
155: }
156:
157: public function mod($other)
158: {
159: return $this->_mod(self::from($other));
160: }
161:
162:
163:
164: private function _pow(BigInt $other)
165: {
166: return new BigInt(bcpow($this->value, $other->value, 0));
167: }
168:
169: public function pow($other)
170: {
171: return $this->_pow(self::from($other));
172: }
173:
174: private function _powmod(BigInt $other, BigInt $modulus)
175: {
176: return new BigInt(bcpowmod($this->value, $other->value, $modulus->value, 0));
177: }
178:
179: public function powmod($other, $modulus)
180: {
181: return $this->_powmod(self::from($other), self::from($modulus));
182: }
183:
184: public function sqrt()
185: {
186: return new BigInt(bcsqrt($this->value, 0));
187: }
188:
189:
190:
191: public function __toString()
192: {
193: return $this->value;
194: }
195: }
196: