PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Calculation / Engineering / BitWise.php

BitWise.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Calculation/Engineering/BitWise.php

253 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Engineering;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Exception;
7 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
8
9 class BitWise
10 {
11 use ArrayEnabled;
12
13 const SPLIT_DIVISOR = 2 ** 24;
14
15 /**
16 * Split a number into upper and lower portions for full 32-bit support.
17 *
18 * @return int[]
19 * @param float|int $number
20 */
21 private static function splitNumber($number): array
22 {
23 return [(int) floor($number / self::SPLIT_DIVISOR), (int) fmod($number, self::SPLIT_DIVISOR)];
24 }
25
26 /**
27 * BITAND.
28 *
29 * Returns the bitwise AND of two integer values.
30 *
31 * Excel Function:
32 * BITAND(number1, number2)
33 *
34 * @param null|array<mixed>|bool|float|int|string $number1 Or can be an array of values
35 * @param null|array<mixed>|bool|float|int|string $number2 Or can be an array of values
36 *
37 * @return array<mixed>|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
38 * with the same dimensions
39 */
40 public static function BITAND($number1, $number2)
41 {
42 if (is_array($number1) || is_array($number2)) {
43 return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2);
44 }
45
46 try {
47 $number1 = self::validateBitwiseArgument($number1);
48 $number2 = self::validateBitwiseArgument($number2);
49 } catch (Exception $e) {
50 return $e->getMessage();
51 }
52 $split1 = self::splitNumber($number1);
53 $split2 = self::splitNumber($number2);
54
55 return self::SPLIT_DIVISOR * ($split1[0] & $split2[0]) + ($split1[1] & $split2[1]);
56 }
57
58 /**
59 * BITOR.
60 *
61 * Returns the bitwise OR of two integer values.
62 *
63 * Excel Function:
64 * BITOR(number1, number2)
65 *
66 * @param null|array<mixed>|bool|float|int|string $number1 Or can be an array of values
67 * @param null|array<mixed>|bool|float|int|string $number2 Or can be an array of values
68 *
69 * @return array<mixed>|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
70 * with the same dimensions
71 */
72 public static function BITOR($number1, $number2)
73 {
74 if (is_array($number1) || is_array($number2)) {
75 return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2);
76 }
77
78 try {
79 $number1 = self::validateBitwiseArgument($number1);
80 $number2 = self::validateBitwiseArgument($number2);
81 } catch (Exception $e) {
82 return $e->getMessage();
83 }
84
85 $split1 = self::splitNumber($number1);
86 $split2 = self::splitNumber($number2);
87
88 return self::SPLIT_DIVISOR * ($split1[0] | $split2[0]) + ($split1[1] | $split2[1]);
89 }
90
91 /**
92 * BITXOR.
93 *
94 * Returns the bitwise XOR of two integer values.
95 *
96 * Excel Function:
97 * BITXOR(number1, number2)
98 *
99 * @param null|array<mixed>|bool|float|int|string $number1 Or can be an array of values
100 * @param null|array<mixed>|bool|float|int|string $number2 Or can be an array of values
101 *
102 * @return array<mixed>|int|string If an array of numbers is passed as an argument, then the returned result will also be an array
103 * with the same dimensions
104 */
105 public static function BITXOR($number1, $number2)
106 {
107 if (is_array($number1) || is_array($number2)) {
108 return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2);
109 }
110
111 try {
112 $number1 = self::validateBitwiseArgument($number1);
113 $number2 = self::validateBitwiseArgument($number2);
114 } catch (Exception $e) {
115 return $e->getMessage();
116 }
117
118 $split1 = self::splitNumber($number1);
119 $split2 = self::splitNumber($number2);
120
121 return self::SPLIT_DIVISOR * ($split1[0] ^ $split2[0]) + ($split1[1] ^ $split2[1]);
122 }
123
124 /**
125 * BITLSHIFT.
126 *
127 * Returns the number value shifted left by shift_amount bits.
128 *
129 * Excel Function:
130 * BITLSHIFT(number, shift_amount)
131 *
132 * @param null|array<mixed>|bool|float|int|string $number Or can be an array of values
133 * @param null|array<mixed>|bool|float|int|string $shiftAmount Or can be an array of values
134 *
135 * @return array<mixed>|float|string If an array of numbers is passed as an argument, then the returned result will also be an array
136 * with the same dimensions
137 */
138 public static function BITLSHIFT($number, $shiftAmount)
139 {
140 if (is_array($number) || is_array($shiftAmount)) {
141 return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount);
142 }
143
144 try {
145 $number = self::validateBitwiseArgument($number);
146 $shiftAmount = self::validateShiftAmount($shiftAmount);
147 } catch (Exception $e) {
148 return $e->getMessage();
149 }
150
151 $result = floor($number * (2 ** $shiftAmount));
152 if ($result > 2 ** 48 - 1) {
153 return ExcelError::NAN();
154 }
155
156 return $result;
157 }
158
159 /**
160 * BITRSHIFT.
161 *
162 * Returns the number value shifted right by shift_amount bits.
163 *
164 * Excel Function:
165 * BITRSHIFT(number, shift_amount)
166 *
167 * @param null|array<mixed>|bool|float|int|string $number Or can be an array of values
168 * @param null|array<mixed>|bool|float|int|string $shiftAmount Or can be an array of values
169 *
170 * @return array<mixed>|float|string If an array of numbers is passed as an argument, then the returned result will also be an array
171 * with the same dimensions
172 */
173 public static function BITRSHIFT($number, $shiftAmount)
174 {
175 if (is_array($number) || is_array($shiftAmount)) {
176 return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount);
177 }
178
179 try {
180 $number = self::validateBitwiseArgument($number);
181 $shiftAmount = self::validateShiftAmount($shiftAmount);
182 } catch (Exception $e) {
183 return $e->getMessage();
184 }
185
186 $result = floor($number / (2 ** $shiftAmount));
187 if ($result > 2 ** 48 - 1) { // possible because shiftAmount can be negative
188 return ExcelError::NAN();
189 }
190
191 return $result;
192 }
193
194 /**
195 * Validate arguments passed to the bitwise functions.
196 * @param mixed $value
197 */
198 private static function validateBitwiseArgument($value): float
199 {
200 $value = self::nullFalseTrueToNumber($value);
201
202 if (is_numeric($value)) {
203 $value = (float) $value;
204 if ($value == floor($value)) {
205 if (($value > 2 ** 48 - 1) || ($value < 0)) {
206 throw new Exception(ExcelError::NAN());
207 }
208
209 return floor($value);
210 }
211
212 throw new Exception(ExcelError::NAN());
213 }
214
215 throw new Exception(ExcelError::VALUE());
216 }
217
218 /**
219 * Validate arguments passed to the bitwise functions.
220 * @param mixed $value
221 */
222 private static function validateShiftAmount($value): int
223 {
224 $value = self::nullFalseTrueToNumber($value);
225
226 if (is_numeric($value)) {
227 if (abs($value + 0) > 53) {
228 throw new Exception(ExcelError::NAN());
229 }
230
231 return (int) $value;
232 }
233
234 throw new Exception(ExcelError::VALUE());
235 }
236
237 /**
238 * Many functions accept null/false/true argument treated as 0/0/1.
239 * @param mixed $number
240 * @return mixed
241 */
242 private static function nullFalseTrueToNumber(&$number)
243 {
244 if ($number === null) {
245 $number = 0;
246 } elseif (is_bool($number)) {
247 $number = (int) $number;
248 }
249
250 return $number;
251 }
252 }
253