Mercurial > hg > octave-lyh
annotate src/bitfcns.cc @ 8500:aaddb450b9aa
[docs] can not => cannot
author | Brian Gough <bjg@gnu.org> |
---|---|
date | Tue, 13 Jan 2009 00:36:52 -0500 |
parents | 9e18aff77e9e |
children | 8463d1a2e544 |
rev | line source |
---|---|
4908 | 1 /* |
2 | |
7017 | 3 Copyright (C) 2004, 2005, 2006, 2007 John W. Eaton |
4908 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
4908 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
4908 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include "str-vec.h" | |
28 #include "quit.h" | |
29 | |
30 #include "defun.h" | |
31 #include "error.h" | |
32 #include "ov.h" | |
33 #include "ov-uint64.h" | |
4915 | 34 #include "ov-uint32.h" |
35 #include "ov-uint16.h" | |
36 #include "ov-uint8.h" | |
37 #include "ov-int64.h" | |
38 #include "ov-int32.h" | |
39 #include "ov-int16.h" | |
40 #include "ov-int8.h" | |
41 #include "ov-scalar.h" | |
42 #include "ov-re-mat.h" | |
7763
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
43 #include "ov-bool.h" |
4908 | 44 |
5775 | 45 // FIXME -- could probably eliminate some code duplication by |
4908 | 46 // clever use of templates. |
47 | |
4915 | 48 #define BITOPX(OP, FNAME, RET) \ |
49 { \ | |
50 int nelx = x.numel (); \ | |
51 int nely = y.numel (); \ | |
52 \ | |
53 bool is_scalar_op = (nelx == 1 || nely == 1); \ | |
54 \ | |
55 dim_vector dvx = x.dims (); \ | |
56 dim_vector dvy = y.dims (); \ | |
57 \ | |
58 bool is_array_op = (dvx == dvy); \ | |
59 \ | |
60 if (is_array_op || is_scalar_op) \ | |
61 { \ | |
62 RET result; \ | |
63 \ | |
64 if (nelx != 1) \ | |
65 result.resize (dvx); \ | |
66 else \ | |
67 result.resize (dvy); \ | |
68 \ | |
69 for (int i = 0; i < nelx; i++) \ | |
70 if (is_scalar_op) \ | |
71 for (int k = 0; k < nely; k++) \ | |
72 result(i+k) = x(i) OP y(k); \ | |
73 else \ | |
74 result(i) = x(i) OP y(i); \ | |
75 \ | |
76 retval = result; \ | |
77 } \ | |
78 else \ | |
79 error ("%s: size of x and y must match, or one operand must be a scalar", FNAME); \ | |
80 } | |
81 | |
4908 | 82 #define BITOP(OP, FNAME) \ |
83 \ | |
84 octave_value retval; \ | |
85 \ | |
86 int nargin = args.length (); \ | |
87 \ | |
88 if (nargin == 2) \ | |
89 { \ | |
4952 | 90 if ((args(0).class_name () == octave_scalar::static_class_name ()) \ |
7763
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
91 || (args(0).class_name () == octave_bool::static_class_name ()) \ |
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
92 || (args(1).class_name () == octave_scalar::static_class_name ()) \ |
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
93 || (args(1).class_name () == octave_bool::static_class_name ())) \ |
4908 | 94 { \ |
4952 | 95 bool arg0_is_int = (args(0).class_name () != \ |
7763
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
96 octave_scalar::static_class_name () && \ |
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
97 args(0).class_name () != \ |
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
98 octave_bool::static_class_name ()); \ |
4952 | 99 bool arg1_is_int = (args(1).class_name () != \ |
7763
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
100 octave_scalar::static_class_name () && \ |
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
101 args(1).class_name () != \ |
0c6b4c7d7117
Treat bool as a scalar in the bit functions
David Bateman <dbateman@free.fr>
parents:
7097
diff
changeset
|
102 octave_bool::static_class_name ()); \ |
4952 | 103 \ |
104 if (! (arg0_is_int || arg1_is_int)) \ | |
4915 | 105 { \ |
4919 | 106 uint64NDArray x (args(0).array_value ()); \ |
4915 | 107 uint64NDArray y (args(1).array_value ()); \ |
4919 | 108 if (! error_state) \ |
109 BITOPX (OP, FNAME, uint64NDArray); \ | |
110 retval = retval.array_value (); \ | |
4908 | 111 } \ |
112 else \ | |
4915 | 113 { \ |
114 int p = (arg0_is_int ? 1 : 0); \ | |
115 int q = (arg0_is_int ? 0 : 1); \ | |
4919 | 116 \ |
4915 | 117 NDArray dx = args(p).array_value (); \ |
118 \ | |
4919 | 119 if (args(q).type_id () == octave_uint64_matrix::static_type_id () \ |
120 || args(q).type_id () == octave_uint64_scalar::static_type_id ()) \ | |
121 { \ | |
122 uint64NDArray x (dx); \ | |
123 uint64NDArray y = args(q).uint64_array_value (); \ | |
124 if (! error_state) \ | |
125 BITOPX (OP, FNAME, uint64NDArray); \ | |
4915 | 126 } \ |
4919 | 127 else if (args(q).type_id () == octave_uint32_matrix::static_type_id () \ |
128 || args(q).type_id () == octave_uint32_scalar::static_type_id ()) \ | |
129 { \ | |
130 uint32NDArray x (dx); \ | |
131 uint32NDArray y = args(q).uint32_array_value (); \ | |
132 if (! error_state) \ | |
133 BITOPX (OP, FNAME, uint32NDArray); \ | |
134 } \ | |
135 else if (args(q).type_id () == octave_uint16_matrix::static_type_id () \ | |
136 || args(q).type_id () == octave_uint16_scalar::static_type_id ()) \ | |
137 { \ | |
138 uint16NDArray x (dx); \ | |
139 uint16NDArray y = args(q).uint16_array_value (); \ | |
140 if (! error_state) \ | |
141 BITOPX (OP, FNAME, uint16NDArray); \ | |
142 } \ | |
143 else if (args(q).type_id () == octave_uint8_matrix::static_type_id () \ | |
144 || args(q).type_id () == octave_uint8_scalar::static_type_id ()) \ | |
145 { \ | |
146 uint8NDArray x (dx); \ | |
147 uint8NDArray y = args(q).uint8_array_value (); \ | |
148 if (! error_state) \ | |
149 BITOPX (OP, FNAME, uint8NDArray); \ | |
4915 | 150 } \ |
4919 | 151 else if (args(q).type_id () == octave_int64_matrix::static_type_id () \ |
152 || args(q).type_id () == octave_int64_scalar::static_type_id ()) \ | |
153 { \ | |
154 int64NDArray x (dx); \ | |
155 int64NDArray y = args(q).int64_array_value (); \ | |
156 if (! error_state) \ | |
157 BITOPX (OP, FNAME, int64NDArray); \ | |
158 } \ | |
159 else if (args(q).type_id () == octave_int32_matrix::static_type_id () \ | |
160 || args(q).type_id () == octave_int32_scalar::static_type_id ()) \ | |
161 { \ | |
162 int32NDArray x (dx); \ | |
163 int32NDArray y = args(q).int32_array_value (); \ | |
164 if (! error_state) \ | |
165 BITOPX (OP, FNAME, int32NDArray); \ | |
166 } \ | |
167 else if (args(q).type_id () == octave_int16_matrix::static_type_id () \ | |
168 || args(q).type_id () == octave_int16_scalar::static_type_id ()) \ | |
169 { \ | |
170 int16NDArray x (dx); \ | |
171 int16NDArray y = args(q).int16_array_value (); \ | |
172 if (! error_state) \ | |
173 BITOPX (OP, FNAME, int16NDArray); \ | |
174 } \ | |
175 else if (args(q).type_id () == octave_int8_matrix::static_type_id () \ | |
176 || args(q).type_id () == octave_int8_scalar::static_type_id ()) \ | |
177 { \ | |
178 int8NDArray x (dx); \ | |
179 int8NDArray y = args(q).int8_array_value (); \ | |
180 if (! error_state) \ | |
181 BITOPX (OP, FNAME, int8NDArray); \ | |
4915 | 182 } \ |
4919 | 183 else \ |
184 error ("%s: invalid operand type", FNAME); \ | |
185 } \ | |
186 } \ | |
4952 | 187 else if (args(0).class_name () == args(1).class_name ()) \ |
4915 | 188 { \ |
4919 | 189 if (args(0).type_id () == octave_uint64_matrix::static_type_id () \ |
190 || args(0).type_id () == octave_uint64_scalar::static_type_id ()) \ | |
191 { \ | |
192 uint64NDArray x = args(0).uint64_array_value (); \ | |
193 uint64NDArray y = args(1).uint64_array_value (); \ | |
194 if (! error_state) \ | |
195 BITOPX (OP, FNAME, uint64NDArray); \ | |
196 } \ | |
197 else if (args(0).type_id () == octave_uint32_matrix::static_type_id () \ | |
198 || args(0).type_id () == octave_uint32_scalar::static_type_id ()) \ | |
4915 | 199 { \ |
4919 | 200 uint32NDArray x = args(0).uint32_array_value (); \ |
201 uint32NDArray y = args(1).uint32_array_value (); \ | |
202 if (! error_state) \ | |
203 BITOPX (OP, FNAME, uint32NDArray); \ | |
204 } \ | |
205 else if (args(0).type_id () == octave_uint16_matrix::static_type_id () \ | |
206 || args(0).type_id () == octave_uint16_scalar::static_type_id ()) \ | |
207 { \ | |
208 uint16NDArray x = args(0).uint16_array_value (); \ | |
209 uint16NDArray y = args(1).uint16_array_value (); \ | |
210 if (! error_state) \ | |
211 BITOPX (OP, FNAME, uint16NDArray); \ | |
4915 | 212 } \ |
4919 | 213 else if (args(0).type_id () == octave_uint8_matrix::static_type_id () \ |
214 || args(0).type_id () == octave_uint8_scalar::static_type_id ()) \ | |
4915 | 215 { \ |
4919 | 216 uint8NDArray x = args(0).uint8_array_value (); \ |
217 uint8NDArray y = args(1).uint8_array_value (); \ | |
218 if (! error_state) \ | |
219 BITOPX (OP, FNAME, uint8NDArray); \ | |
4915 | 220 } \ |
4919 | 221 else if (args(0).type_id () == octave_int64_matrix::static_type_id () \ |
222 || args(0).type_id () == octave_int64_scalar::static_type_id ()) \ | |
4915 | 223 { \ |
4919 | 224 int64NDArray x = args(0).int64_array_value (); \ |
225 int64NDArray y = args(1).int64_array_value (); \ | |
226 if (! error_state) \ | |
227 BITOPX (OP, FNAME, int64NDArray); \ | |
4915 | 228 } \ |
4919 | 229 else if (args(0).type_id () == octave_int32_matrix::static_type_id () \ |
230 || args(0).type_id () == octave_int32_scalar::static_type_id ()) \ | |
4915 | 231 { \ |
4919 | 232 int32NDArray x = args(0).int32_array_value (); \ |
233 int32NDArray y = args(1).int32_array_value (); \ | |
234 if (! error_state) \ | |
235 BITOPX (OP, FNAME, int32NDArray); \ | |
4915 | 236 } \ |
4919 | 237 else if (args(0).type_id () == octave_int16_matrix::static_type_id () \ |
238 || args(0).type_id () == octave_int16_scalar::static_type_id ()) \ | |
4915 | 239 { \ |
4919 | 240 int16NDArray x = args(0).int16_array_value (); \ |
241 int16NDArray y = args(1).int16_array_value (); \ | |
242 if (! error_state) \ | |
243 BITOPX (OP, FNAME, int16NDArray); \ | |
4915 | 244 } \ |
4919 | 245 else if (args(0).type_id () == octave_int8_matrix::static_type_id () \ |
246 || args(0).type_id () == octave_int8_scalar::static_type_id ()) \ | |
4915 | 247 { \ |
4919 | 248 int8NDArray x = args(0).int8_array_value (); \ |
249 int8NDArray y = args(1).int8_array_value (); \ | |
250 if (! error_state) \ | |
251 BITOPX (OP, FNAME, int8NDArray); \ | |
4915 | 252 } \ |
253 else \ | |
4919 | 254 error ("%s: invalid operand type", FNAME); \ |
4915 | 255 } \ |
4908 | 256 else \ |
4915 | 257 error ("%s: must have matching operand types", FNAME); \ |
4908 | 258 } \ |
259 else \ | |
5823 | 260 print_usage (); \ |
4908 | 261 \ |
262 return retval | |
263 | |
264 DEFUN (bitand, args, , | |
265 "-*- texinfo -*-\n\ | |
266 @deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})\n\ | |
4920 | 267 Return the bitwise AND of nonnegative integers.\n\ |
4908 | 268 @var{x}, @var{y} must be in range [0..bitmax]\n\ |
5642 | 269 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ |
270 @end deftypefn") | |
4908 | 271 { |
272 BITOP (&, "bitand"); | |
273 } | |
274 | |
275 DEFUN (bitor, args, , | |
276 "-*- texinfo -*-\n\ | |
277 @deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})\n\ | |
4920 | 278 Return the bitwise OR of nonnegative integers.\n\ |
4908 | 279 @var{x}, @var{y} must be in range [0..bitmax]\n\ |
5642 | 280 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ |
281 @end deftypefn") | |
4908 | 282 { |
283 BITOP (|, "bitor"); | |
284 } | |
285 | |
286 DEFUN (bitxor, args, , | |
287 "-*- texinfo -*-\n\ | |
288 @deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})\n\ | |
4920 | 289 Return the bitwise XOR of nonnegative integers.\n\ |
4908 | 290 @var{x}, @var{y} must be in range [0..bitmax]\n\ |
5642 | 291 @seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ |
292 @end deftypefn") | |
4908 | 293 { |
294 BITOP (^, "bitxor"); | |
295 } | |
296 | |
5828 | 297 static int64_t |
298 bitshift (double a, int n, int64_t mask) | |
4908 | 299 { |
6108 | 300 // In the name of bug-for-bug compatibility. |
301 if (a < 0) | |
302 return -bitshift (-a, n, mask); | |
303 | |
4915 | 304 if (n > 0) |
5828 | 305 return (static_cast<int64_t> (a) << n) & mask; |
4915 | 306 else if (n < 0) |
5828 | 307 return (static_cast<int64_t> (a) >> -n) & mask; |
4915 | 308 else |
5828 | 309 return static_cast<int64_t> (a) & mask; |
4908 | 310 } |
311 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
312 static int64_t |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
313 bitshift (float a, int n, int64_t mask) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
314 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
315 // In the name of bug-for-bug compatibility. |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
316 if (a < 0) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
317 return -bitshift (-a, n, mask); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
318 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
319 if (n > 0) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
320 return (static_cast<int64_t> (a) << n) & mask; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
321 else if (n < 0) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
322 return (static_cast<int64_t> (a) >> -n) & mask; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
323 else |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
324 return static_cast<int64_t> (a) & mask; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
325 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7763
diff
changeset
|
326 |
4919 | 327 // Note that the bitshift operators are undefined if shifted by more |
328 // bits than in the type, so we need to test for the size of the | |
329 // shift. | |
330 | |
4908 | 331 #define DO_BITSHIFT(T) \ |
4919 | 332 if (! error_state) \ |
333 { \ | |
334 double d1, d2; \ | |
4908 | 335 \ |
4919 | 336 if (n.all_integers (d1, d2)) \ |
337 { \ | |
338 int m_nel = m.numel (); \ | |
339 int n_nel = n.numel (); \ | |
4908 | 340 \ |
4919 | 341 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \ |
4908 | 342 \ |
4919 | 343 dim_vector m_dv = m.dims (); \ |
344 dim_vector n_dv = n.dims (); \ | |
345 \ | |
346 bool is_array_op = (m_dv == n_dv); \ | |
4908 | 347 \ |
4919 | 348 if (is_array_op || is_scalar_op) \ |
349 { \ | |
350 T ## NDArray result; \ | |
4908 | 351 \ |
4919 | 352 if (m_nel != 1) \ |
353 result.resize (m_dv); \ | |
354 else \ | |
355 result.resize (n_dv); \ | |
4908 | 356 \ |
4919 | 357 for (int i = 0; i < m_nel; i++) \ |
358 if (is_scalar_op) \ | |
359 for (int k = 0; k < n_nel; k++) \ | |
360 if (static_cast<int> (n(k)) >= bits_in_type) \ | |
361 result(i+k) = 0; \ | |
4908 | 362 else \ |
4920 | 363 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \ |
4919 | 364 else \ |
365 if (static_cast<int> (n(i)) >= bits_in_type) \ | |
366 result(i) = 0; \ | |
367 else \ | |
4920 | 368 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \ |
4908 | 369 \ |
4919 | 370 retval = result; \ |
4908 | 371 } \ |
4919 | 372 else \ |
373 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \ | |
374 } \ | |
375 else \ | |
376 error ("bitshift: expecting second argument to be integer"); \ | |
377 } | |
4915 | 378 |
4919 | 379 #define DO_UBITSHIFT(T, N) \ |
380 do \ | |
381 { \ | |
4920 | 382 int bits_in_type = octave_ ## T :: nbits (); \ |
4919 | 383 T ## NDArray m = m_arg.T ## _array_value (); \ |
384 octave_ ## T mask = ~0ULL; \ | |
4920 | 385 if ((N) < bits_in_type) \ |
386 mask = bitshift (mask, (N) - bits_in_type); \ | |
4919 | 387 else if ((N) < 1) \ |
388 mask = 0; \ | |
389 DO_BITSHIFT (T); \ | |
390 } \ | |
4915 | 391 while (0) |
392 | |
4919 | 393 #define DO_SBITSHIFT(T, N) \ |
394 do \ | |
395 { \ | |
4920 | 396 int bits_in_type = octave_ ## T :: nbits (); \ |
4919 | 397 T ## NDArray m = m_arg.T ## _array_value (); \ |
398 octave_ ## T mask = -1; \ | |
4920 | 399 if ((N) < bits_in_type) \ |
400 mask = bitshift (mask, (N) - bits_in_type); \ | |
4919 | 401 else if ((N) < 1) \ |
402 mask = 0; \ | |
403 DO_BITSHIFT (T); \ | |
404 } \ | |
4908 | 405 while (0) |
406 | |
407 DEFUN (bitshift, args, , | |
408 "-*- texinfo -*-\n\ | |
6678 | 409 @deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})\n\ |
410 @deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})\n\ | |
8492 | 411 Return a @var{k} bit shift of @var{n}-digit unsigned\n\ |
4920 | 412 integers in @var{a}. A positive @var{k} leads to a left shift.\n\ |
413 A negative value to a right shift. If @var{n} is omitted it defaults\n\ | |
414 to log2(bitmax)+1.\n\ | |
8347
fa78cb8d8a5c
corrections for typos
Brian Gough<bjg@network-theory.co.uk>
parents:
8325
diff
changeset
|
415 @var{n} must be in the range [1,log2(bitmax)+1] usually [1,33]\n\ |
4908 | 416 \n\ |
417 @example\n\ | |
7097 | 418 bitshift (eye (3), 1)\n\ |
4908 | 419 @result{}\n\ |
420 @group\n\ | |
421 2 0 0\n\ | |
422 0 2 0\n\ | |
423 0 0 2\n\ | |
424 @end group\n\ | |
425 \n\ | |
426 bitshift (10, [-2, -1, 0, 1, 2])\n\ | |
427 @result{} 2 5 10 20 40\n\ | |
6439 | 428 @c FIXME -- restore this example when third arg is allowed to be an array.\n\ |
429 @c \n\ | |
430 @c \n\ | |
431 @c bitshift ([1, 10], 2, [3,4])\n\ | |
432 @c @result{} 4 8\n\ | |
4908 | 433 @end example\n\ |
5642 | 434 @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax}\n\ |
435 @end deftypefn") | |
4908 | 436 { |
437 octave_value retval; | |
438 | |
439 int nargin = args.length (); | |
440 | |
4915 | 441 if (nargin == 2 || nargin == 3) |
4908 | 442 { |
4915 | 443 int nbits = 64; |
444 | |
4920 | 445 NDArray n = args(1).array_value (); |
446 | |
447 if (error_state) | |
448 error ("bitshift: expecting integer as second argument"); | |
449 else | |
4915 | 450 { |
4920 | 451 if (nargin == 3) |
452 { | |
6439 | 453 // FIXME -- for compatibility, we should accept an array |
454 // or a scalar as the third argument. | |
455 if (args(2).numel () > 1) | |
456 error ("bitshift: expecting scalar integer as third argument"); | |
457 else | |
458 { | |
459 nbits = args(2).int_value (); | |
4915 | 460 |
6439 | 461 if (error_state) |
462 error ("bitshift: expecting integer as third argument"); | |
463 else if (nbits < 0) | |
464 error ("bitshift: number of bits to mask must be positive"); | |
465 } | |
4920 | 466 } |
4915 | 467 } |
468 | |
469 if (error_state) | |
470 return retval; | |
4908 | 471 |
472 octave_value m_arg = args(0); | |
473 std::string cname = m_arg.class_name (); | |
474 | |
475 if (cname == "uint8") | |
4915 | 476 DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8); |
4908 | 477 else if (cname == "uint16") |
4915 | 478 DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16); |
4908 | 479 else if (cname == "uint32") |
4915 | 480 DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32); |
4908 | 481 else if (cname == "uint64") |
4915 | 482 DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64); |
483 else if (cname == "int8") | |
484 DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8); | |
485 else if (cname == "int16") | |
486 DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16); | |
487 else if (cname == "int32") | |
488 DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32); | |
489 else if (cname == "int64") | |
490 DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64); | |
491 else if (cname == "double") | |
492 { | |
493 nbits = (nbits < 53 ? nbits : 53); | |
5828 | 494 int64_t mask = 0x1FFFFFFFFFFFFFLL; |
4915 | 495 if (nbits < 53) |
496 mask = mask >> (53 - nbits); | |
497 else if (nbits < 1) | |
498 mask = 0; | |
499 int bits_in_type = 64; | |
500 NDArray m = m_arg.array_value (); | |
501 DO_BITSHIFT ( ); | |
502 } | |
4908 | 503 else |
504 error ("bitshift: not defined for %s objects", cname.c_str ()); | |
505 } | |
506 else | |
5823 | 507 print_usage (); |
4908 | 508 |
509 return retval; | |
510 } | |
511 | |
512 DEFUN (bitmax, args, , | |
513 "-*- texinfo -*-\n\ | |
4915 | 514 @deftypefn {Built-in Function} {} bitmax ()\n\ |
4920 | 515 Return the largest integer that can be represented as a floating point\n\ |
8325
b93ac0586e4b
spelling corrections
Brian Gough<bjg@network-theory.co.uk>
parents:
7789
diff
changeset
|
516 value. On IEEE-754 compatible systems, @code{bitmax} is @code{2^53 - 1}.\n\ |
4915 | 517 @end deftypefn") |
518 { | |
519 octave_value retval; | |
4919 | 520 if (args.length () != 0) |
5823 | 521 print_usage (); |
4915 | 522 else |
4919 | 523 retval = (static_cast<double> (0x1FFFFFFFFFFFFFLL)); |
4915 | 524 return retval; |
525 } | |
526 | |
527 DEFUN (intmax, args, , | |
528 "-*- texinfo -*-\n\ | |
529 @deftypefn {Built-in Function} {} intmax (@var{type})\n\ | |
5040 | 530 Return the largest integer that can be represented in an integer type.\n\ |
531 The variable @var{type} can be\n\ | |
532 \n\ | |
533 @table @code\n\ | |
534 @item int8\n\ | |
535 signed 8-bit integer.\n\ | |
536 @item int16\n\ | |
537 signed 16-bit integer.\n\ | |
538 @item int32\n\ | |
539 signed 32-bit integer.\n\ | |
540 @item int64\n\ | |
541 signed 64-bit integer.\n\ | |
542 @item uint8\n\ | |
543 unsigned 8-bit integer.\n\ | |
544 @item uint16\n\ | |
545 unsigned 16-bit integer.\n\ | |
546 @item uint32\n\ | |
547 unsigned 32-bit integer.\n\ | |
548 @item uint64\n\ | |
549 unsigned 64-bit integer.\n\ | |
550 @end table\n\ | |
551 \n\ | |
552 The default for @var{type} is @code{uint32}.\n\ | |
5642 | 553 @seealso{intmin, bitmax}\n\ |
4908 | 554 @end deftypefn") |
555 { | |
556 octave_value retval; | |
4915 | 557 std::string cname = "int32"; |
558 int nargin = args.length (); | |
559 | |
4919 | 560 if (nargin == 1 && args(0).is_string ()) |
4915 | 561 cname = args(0).string_value (); |
562 else if (nargin != 0) | |
563 { | |
5823 | 564 print_usage (); |
4915 | 565 return retval; |
566 } | |
567 | |
568 if (cname == "uint8") | |
5828 | 569 retval = octave_uint8 (std::numeric_limits<uint8_t>::max ()); |
4915 | 570 else if (cname == "uint16") |
5828 | 571 retval = octave_uint16 (std::numeric_limits<uint16_t>::max ()); |
4915 | 572 else if (cname == "uint32") |
5828 | 573 retval = octave_uint32 (std::numeric_limits<uint32_t>::max ()); |
4915 | 574 else if (cname == "uint64") |
5828 | 575 retval = octave_uint64 (std::numeric_limits<uint64_t>::max ()); |
4915 | 576 else if (cname == "int8") |
5828 | 577 retval = octave_int8 (std::numeric_limits<int8_t>::max ()); |
4915 | 578 else if (cname == "int16") |
5828 | 579 retval = octave_int16 (std::numeric_limits<int16_t>::max ()); |
4915 | 580 else if (cname == "int32") |
5828 | 581 retval = octave_int32 (std::numeric_limits<int32_t>::max ()); |
4915 | 582 else if (cname == "int64") |
5828 | 583 retval = octave_int64 (std::numeric_limits<int64_t>::max ()); |
4915 | 584 else |
585 error ("intmax: not defined for '%s' objects", cname.c_str ()); | |
586 | |
587 return retval; | |
588 } | |
589 | |
590 DEFUN (intmin, args, , | |
591 "-*- texinfo -*-\n\ | |
592 @deftypefn {Built-in Function} {} intmin (@var{type})\n\ | |
5040 | 593 Return the smallest integer that can be represented in an integer type.\n\ |
594 The variable @var{type} can be\n\ | |
595 \n\ | |
596 @table @code\n\ | |
597 @item int8\n\ | |
598 signed 8-bit integer.\n\ | |
599 @item int16\n\ | |
600 signed 16-bit integer.\n\ | |
601 @item int32\n\ | |
602 signed 32-bit integer.\n\ | |
603 @item int64\n\ | |
604 signed 64-bit integer.\n\ | |
605 @item uint8\n\ | |
606 unsigned 8-bit integer.\n\ | |
607 @item uint16\n\ | |
608 unsigned 16-bit integer.\n\ | |
609 @item uint32\n\ | |
610 unsigned 32-bit integer.\n\ | |
611 @item uint64\n\ | |
612 unsigned 64-bit integer.\n\ | |
613 @end table\n\ | |
614 \n\ | |
615 The default for @var{type} is @code{uint32}.\n\ | |
5642 | 616 @seealso{intmax, bitmax}\n\ |
4915 | 617 @end deftypefn") |
618 { | |
619 octave_value retval; | |
620 std::string cname = "int32"; | |
621 int nargin = args.length (); | |
622 | |
4919 | 623 if (nargin == 1 && args(0).is_string ()) |
4915 | 624 cname = args(0).string_value (); |
625 else if (nargin != 0) | |
626 { | |
5823 | 627 print_usage (); |
4915 | 628 return retval; |
629 } | |
630 | |
631 if (cname == "uint8") | |
5828 | 632 retval = octave_uint8 (std::numeric_limits<uint8_t>::min ()); |
4915 | 633 else if (cname == "uint16") |
5828 | 634 retval = octave_uint16 (std::numeric_limits<uint16_t>::min()); |
4915 | 635 else if (cname == "uint32") |
5828 | 636 retval = octave_uint32 (std::numeric_limits<uint32_t>::min ()); |
4915 | 637 else if (cname == "uint64") |
5828 | 638 retval = octave_uint64 (std::numeric_limits<uint64_t>::min ()); |
4915 | 639 else if (cname == "int8") |
5828 | 640 retval = octave_int8 (std::numeric_limits<int8_t>::min ()); |
4915 | 641 else if (cname == "int16") |
5828 | 642 retval = octave_int16 (std::numeric_limits<int16_t>::min ()); |
4915 | 643 else if (cname == "int32") |
5828 | 644 retval = octave_int32 (std::numeric_limits<int32_t>::min ()); |
4915 | 645 else if (cname == "int64") |
5828 | 646 retval = octave_int64 (std::numeric_limits<int64_t>::min ()); |
4915 | 647 else |
648 error ("intmin: not defined for '%s' objects", cname.c_str ()); | |
649 | |
4908 | 650 return retval; |
651 } | |
652 | |
653 /* | |
654 ;;; Local Variables: *** | |
655 ;;; mode: C++ *** | |
656 ;;; End: *** | |
657 */ |