Mercurial > octave
annotate src/bitfcns.cc @ 7763:0c6b4c7d7117
Treat bool as a scalar in the bit functions
author | David Bateman <dbateman@free.fr> |
---|---|
date | Tue, 06 May 2008 06:19:58 -0400 |
parents | e8c94e473c68 |
children | 82be108cc558 3342d1a7c4c9 |
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 | |
4919 | 312 // Note that the bitshift operators are undefined if shifted by more |
313 // bits than in the type, so we need to test for the size of the | |
314 // shift. | |
315 | |
4908 | 316 #define DO_BITSHIFT(T) \ |
4919 | 317 if (! error_state) \ |
318 { \ | |
319 double d1, d2; \ | |
4908 | 320 \ |
4919 | 321 if (n.all_integers (d1, d2)) \ |
322 { \ | |
323 int m_nel = m.numel (); \ | |
324 int n_nel = n.numel (); \ | |
4908 | 325 \ |
4919 | 326 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \ |
4908 | 327 \ |
4919 | 328 dim_vector m_dv = m.dims (); \ |
329 dim_vector n_dv = n.dims (); \ | |
330 \ | |
331 bool is_array_op = (m_dv == n_dv); \ | |
4908 | 332 \ |
4919 | 333 if (is_array_op || is_scalar_op) \ |
334 { \ | |
335 T ## NDArray result; \ | |
4908 | 336 \ |
4919 | 337 if (m_nel != 1) \ |
338 result.resize (m_dv); \ | |
339 else \ | |
340 result.resize (n_dv); \ | |
4908 | 341 \ |
4919 | 342 for (int i = 0; i < m_nel; i++) \ |
343 if (is_scalar_op) \ | |
344 for (int k = 0; k < n_nel; k++) \ | |
345 if (static_cast<int> (n(k)) >= bits_in_type) \ | |
346 result(i+k) = 0; \ | |
4908 | 347 else \ |
4920 | 348 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \ |
4919 | 349 else \ |
350 if (static_cast<int> (n(i)) >= bits_in_type) \ | |
351 result(i) = 0; \ | |
352 else \ | |
4920 | 353 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \ |
4908 | 354 \ |
4919 | 355 retval = result; \ |
4908 | 356 } \ |
4919 | 357 else \ |
358 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \ | |
359 } \ | |
360 else \ | |
361 error ("bitshift: expecting second argument to be integer"); \ | |
362 } | |
4915 | 363 |
4919 | 364 #define DO_UBITSHIFT(T, N) \ |
365 do \ | |
366 { \ | |
4920 | 367 int bits_in_type = octave_ ## T :: nbits (); \ |
4919 | 368 T ## NDArray m = m_arg.T ## _array_value (); \ |
369 octave_ ## T mask = ~0ULL; \ | |
4920 | 370 if ((N) < bits_in_type) \ |
371 mask = bitshift (mask, (N) - bits_in_type); \ | |
4919 | 372 else if ((N) < 1) \ |
373 mask = 0; \ | |
374 DO_BITSHIFT (T); \ | |
375 } \ | |
4915 | 376 while (0) |
377 | |
4919 | 378 #define DO_SBITSHIFT(T, N) \ |
379 do \ | |
380 { \ | |
4920 | 381 int bits_in_type = octave_ ## T :: nbits (); \ |
4919 | 382 T ## NDArray m = m_arg.T ## _array_value (); \ |
383 octave_ ## T mask = -1; \ | |
4920 | 384 if ((N) < bits_in_type) \ |
385 mask = bitshift (mask, (N) - bits_in_type); \ | |
4919 | 386 else if ((N) < 1) \ |
387 mask = 0; \ | |
388 DO_BITSHIFT (T); \ | |
389 } \ | |
4908 | 390 while (0) |
391 | |
392 DEFUN (bitshift, args, , | |
393 "-*- texinfo -*-\n\ | |
6678 | 394 @deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})\n\ |
395 @deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})\n\ | |
4920 | 396 Return a @var{k} bit shift of @var{n}- digit unsigned\n\ |
397 integers in @var{a}. A positive @var{k} leads to a left shift.\n\ | |
398 A negative value to a right shift. If @var{n} is omitted it defaults\n\ | |
399 to log2(bitmax)+1.\n\ | |
4915 | 400 @var{n} must be in range [1,log2(bitmax)+1] usually [1,33]\n\ |
4908 | 401 \n\ |
402 @example\n\ | |
7097 | 403 bitshift (eye (3), 1)\n\ |
4908 | 404 @result{}\n\ |
405 @group\n\ | |
406 2 0 0\n\ | |
407 0 2 0\n\ | |
408 0 0 2\n\ | |
409 @end group\n\ | |
410 \n\ | |
411 bitshift (10, [-2, -1, 0, 1, 2])\n\ | |
412 @result{} 2 5 10 20 40\n\ | |
6439 | 413 @c FIXME -- restore this example when third arg is allowed to be an array.\n\ |
414 @c \n\ | |
415 @c \n\ | |
416 @c bitshift ([1, 10], 2, [3,4])\n\ | |
417 @c @result{} 4 8\n\ | |
4908 | 418 @end example\n\ |
5642 | 419 @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax}\n\ |
420 @end deftypefn") | |
4908 | 421 { |
422 octave_value retval; | |
423 | |
424 int nargin = args.length (); | |
425 | |
4915 | 426 if (nargin == 2 || nargin == 3) |
4908 | 427 { |
4915 | 428 int nbits = 64; |
429 | |
4920 | 430 NDArray n = args(1).array_value (); |
431 | |
432 if (error_state) | |
433 error ("bitshift: expecting integer as second argument"); | |
434 else | |
4915 | 435 { |
4920 | 436 if (nargin == 3) |
437 { | |
6439 | 438 // FIXME -- for compatibility, we should accept an array |
439 // or a scalar as the third argument. | |
440 if (args(2).numel () > 1) | |
441 error ("bitshift: expecting scalar integer as third argument"); | |
442 else | |
443 { | |
444 nbits = args(2).int_value (); | |
4915 | 445 |
6439 | 446 if (error_state) |
447 error ("bitshift: expecting integer as third argument"); | |
448 else if (nbits < 0) | |
449 error ("bitshift: number of bits to mask must be positive"); | |
450 } | |
4920 | 451 } |
4915 | 452 } |
453 | |
454 if (error_state) | |
455 return retval; | |
4908 | 456 |
457 octave_value m_arg = args(0); | |
458 std::string cname = m_arg.class_name (); | |
459 | |
460 if (cname == "uint8") | |
4915 | 461 DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8); |
4908 | 462 else if (cname == "uint16") |
4915 | 463 DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16); |
4908 | 464 else if (cname == "uint32") |
4915 | 465 DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32); |
4908 | 466 else if (cname == "uint64") |
4915 | 467 DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64); |
468 else if (cname == "int8") | |
469 DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8); | |
470 else if (cname == "int16") | |
471 DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16); | |
472 else if (cname == "int32") | |
473 DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32); | |
474 else if (cname == "int64") | |
475 DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64); | |
476 else if (cname == "double") | |
477 { | |
478 nbits = (nbits < 53 ? nbits : 53); | |
5828 | 479 int64_t mask = 0x1FFFFFFFFFFFFFLL; |
4915 | 480 if (nbits < 53) |
481 mask = mask >> (53 - nbits); | |
482 else if (nbits < 1) | |
483 mask = 0; | |
484 int bits_in_type = 64; | |
485 NDArray m = m_arg.array_value (); | |
486 DO_BITSHIFT ( ); | |
487 } | |
4908 | 488 else |
489 error ("bitshift: not defined for %s objects", cname.c_str ()); | |
490 } | |
491 else | |
5823 | 492 print_usage (); |
4908 | 493 |
494 return retval; | |
495 } | |
496 | |
497 DEFUN (bitmax, args, , | |
498 "-*- texinfo -*-\n\ | |
4915 | 499 @deftypefn {Built-in Function} {} bitmax ()\n\ |
4920 | 500 Return the largest integer that can be represented as a floating point\n\ |
501 value. On IEEE-754 compatiable systems, @code{bitmax} is @code{2^53 - 1}.\n\ | |
4915 | 502 @end deftypefn") |
503 { | |
504 octave_value retval; | |
4919 | 505 if (args.length () != 0) |
5823 | 506 print_usage (); |
4915 | 507 else |
4919 | 508 retval = (static_cast<double> (0x1FFFFFFFFFFFFFLL)); |
4915 | 509 return retval; |
510 } | |
511 | |
512 DEFUN (intmax, args, , | |
513 "-*- texinfo -*-\n\ | |
514 @deftypefn {Built-in Function} {} intmax (@var{type})\n\ | |
5040 | 515 Return the largest integer that can be represented in an integer type.\n\ |
516 The variable @var{type} can be\n\ | |
517 \n\ | |
518 @table @code\n\ | |
519 @item int8\n\ | |
520 signed 8-bit integer.\n\ | |
521 @item int16\n\ | |
522 signed 16-bit integer.\n\ | |
523 @item int32\n\ | |
524 signed 32-bit integer.\n\ | |
525 @item int64\n\ | |
526 signed 64-bit integer.\n\ | |
527 @item uint8\n\ | |
528 unsigned 8-bit integer.\n\ | |
529 @item uint16\n\ | |
530 unsigned 16-bit integer.\n\ | |
531 @item uint32\n\ | |
532 unsigned 32-bit integer.\n\ | |
533 @item uint64\n\ | |
534 unsigned 64-bit integer.\n\ | |
535 @end table\n\ | |
536 \n\ | |
537 The default for @var{type} is @code{uint32}.\n\ | |
5642 | 538 @seealso{intmin, bitmax}\n\ |
4908 | 539 @end deftypefn") |
540 { | |
541 octave_value retval; | |
4915 | 542 std::string cname = "int32"; |
543 int nargin = args.length (); | |
544 | |
4919 | 545 if (nargin == 1 && args(0).is_string ()) |
4915 | 546 cname = args(0).string_value (); |
547 else if (nargin != 0) | |
548 { | |
5823 | 549 print_usage (); |
4915 | 550 return retval; |
551 } | |
552 | |
553 if (cname == "uint8") | |
5828 | 554 retval = octave_uint8 (std::numeric_limits<uint8_t>::max ()); |
4915 | 555 else if (cname == "uint16") |
5828 | 556 retval = octave_uint16 (std::numeric_limits<uint16_t>::max ()); |
4915 | 557 else if (cname == "uint32") |
5828 | 558 retval = octave_uint32 (std::numeric_limits<uint32_t>::max ()); |
4915 | 559 else if (cname == "uint64") |
5828 | 560 retval = octave_uint64 (std::numeric_limits<uint64_t>::max ()); |
4915 | 561 else if (cname == "int8") |
5828 | 562 retval = octave_int8 (std::numeric_limits<int8_t>::max ()); |
4915 | 563 else if (cname == "int16") |
5828 | 564 retval = octave_int16 (std::numeric_limits<int16_t>::max ()); |
4915 | 565 else if (cname == "int32") |
5828 | 566 retval = octave_int32 (std::numeric_limits<int32_t>::max ()); |
4915 | 567 else if (cname == "int64") |
5828 | 568 retval = octave_int64 (std::numeric_limits<int64_t>::max ()); |
4915 | 569 else |
570 error ("intmax: not defined for '%s' objects", cname.c_str ()); | |
571 | |
572 return retval; | |
573 } | |
574 | |
575 DEFUN (intmin, args, , | |
576 "-*- texinfo -*-\n\ | |
577 @deftypefn {Built-in Function} {} intmin (@var{type})\n\ | |
5040 | 578 Return the smallest integer that can be represented in an integer type.\n\ |
579 The variable @var{type} can be\n\ | |
580 \n\ | |
581 @table @code\n\ | |
582 @item int8\n\ | |
583 signed 8-bit integer.\n\ | |
584 @item int16\n\ | |
585 signed 16-bit integer.\n\ | |
586 @item int32\n\ | |
587 signed 32-bit integer.\n\ | |
588 @item int64\n\ | |
589 signed 64-bit integer.\n\ | |
590 @item uint8\n\ | |
591 unsigned 8-bit integer.\n\ | |
592 @item uint16\n\ | |
593 unsigned 16-bit integer.\n\ | |
594 @item uint32\n\ | |
595 unsigned 32-bit integer.\n\ | |
596 @item uint64\n\ | |
597 unsigned 64-bit integer.\n\ | |
598 @end table\n\ | |
599 \n\ | |
600 The default for @var{type} is @code{uint32}.\n\ | |
5642 | 601 @seealso{intmax, bitmax}\n\ |
4915 | 602 @end deftypefn") |
603 { | |
604 octave_value retval; | |
605 std::string cname = "int32"; | |
606 int nargin = args.length (); | |
607 | |
4919 | 608 if (nargin == 1 && args(0).is_string ()) |
4915 | 609 cname = args(0).string_value (); |
610 else if (nargin != 0) | |
611 { | |
5823 | 612 print_usage (); |
4915 | 613 return retval; |
614 } | |
615 | |
616 if (cname == "uint8") | |
5828 | 617 retval = octave_uint8 (std::numeric_limits<uint8_t>::min ()); |
4915 | 618 else if (cname == "uint16") |
5828 | 619 retval = octave_uint16 (std::numeric_limits<uint16_t>::min()); |
4915 | 620 else if (cname == "uint32") |
5828 | 621 retval = octave_uint32 (std::numeric_limits<uint32_t>::min ()); |
4915 | 622 else if (cname == "uint64") |
5828 | 623 retval = octave_uint64 (std::numeric_limits<uint64_t>::min ()); |
4915 | 624 else if (cname == "int8") |
5828 | 625 retval = octave_int8 (std::numeric_limits<int8_t>::min ()); |
4915 | 626 else if (cname == "int16") |
5828 | 627 retval = octave_int16 (std::numeric_limits<int16_t>::min ()); |
4915 | 628 else if (cname == "int32") |
5828 | 629 retval = octave_int32 (std::numeric_limits<int32_t>::min ()); |
4915 | 630 else if (cname == "int64") |
5828 | 631 retval = octave_int64 (std::numeric_limits<int64_t>::min ()); |
4915 | 632 else |
633 error ("intmin: not defined for '%s' objects", cname.c_str ()); | |
634 | |
4908 | 635 return retval; |
636 } | |
637 | |
638 /* | |
639 ;;; Local Variables: *** | |
640 ;;; mode: C++ *** | |
641 ;;; End: *** | |
642 */ |