Mercurial > hg > octave-nkf
comparison libinterp/corefcn/bitfcns.cc @ 15195:2fc554ffbc28
split libinterp from src
* libinterp: New directory. Move all files from src directory here
except Makefile.am, main.cc, main-cli.cc, mkoctfile.in.cc,
mkoctfilr.in.sh, octave-config.in.cc, octave-config.in.sh.
* libinterp/Makefile.am: New file, extracted from src/Makefile.am.
* src/Makefile.am: Delete everything except targets and definitions
needed to build and link main and utility programs.
* Makefile.am (SUBDIRS): Include libinterp in the list.
* autogen.sh: Run config-module.sh in libinterp/dldfcn directory, not
src/dldfcn directory.
* configure.ac (AC_CONFIG_SRCDIR): Use libinterp/octave.cc, not
src/octave.cc.
(DL_LDFLAGS, LIBOCTINTERP): Use libinterp, not src.
(AC_CONFIG_FILES): Include libinterp/Makefile in the list.
* find-docstring-files.sh: Look in libinterp, not src.
* gui/src/Makefile.am (liboctgui_la_CPPFLAGS): Find header files in
libinterp, not src.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 18 Aug 2012 16:23:39 -0400 |
parents | src/corefcn/bitfcns.cc@b62b0b85369c |
children | 06897f865f0b |
comparison
equal
deleted
inserted
replaced
15194:0f0b795044c3 | 15195:2fc554ffbc28 |
---|---|
1 /* | |
2 | |
3 Copyright (C) 2004-2012 John W. Eaton | |
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 | |
9 Free Software Foundation; either version 3 of the License, or (at your | |
10 option) any later version. | |
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 | |
18 along with Octave; see the file COPYING. If not, see | |
19 <http://www.gnu.org/licenses/>. | |
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" | |
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" | |
43 #include "ov-bool.h" | |
44 | |
45 #include <functional> | |
46 | |
47 #if !defined (HAVE_CXX_BITWISE_OP_TEMPLATES) | |
48 namespace std | |
49 { | |
50 template <typename T> | |
51 struct bit_and | |
52 { | |
53 public: | |
54 T operator() (const T & op1, const T & op2) const { return (op1 & op2); } | |
55 }; | |
56 | |
57 template <typename T> | |
58 struct bit_or | |
59 { | |
60 public: | |
61 T operator() (const T & op1, const T & op2) const { return (op1 | op2); } | |
62 }; | |
63 | |
64 template <typename T> | |
65 struct bit_xor | |
66 { | |
67 public: | |
68 T operator() (const T & op1, const T & op2) const { return (op1 ^ op2); } | |
69 }; | |
70 } | |
71 #endif | |
72 | |
73 template <typename OP, typename T> | |
74 octave_value | |
75 bitopxx (const OP& op, const std::string& fname, | |
76 const Array<T>& x, const Array<T>& y) | |
77 { | |
78 int nelx = x.numel (); | |
79 int nely = y.numel (); | |
80 | |
81 bool is_scalar_op = (nelx == 1 || nely == 1); | |
82 | |
83 dim_vector dvx = x.dims (); | |
84 dim_vector dvy = y.dims (); | |
85 | |
86 bool is_array_op = (dvx == dvy); | |
87 | |
88 octave_value retval; | |
89 if (is_array_op || is_scalar_op) | |
90 { | |
91 Array<T> result; | |
92 | |
93 if (nelx != 1) | |
94 result.resize (dvx); | |
95 else | |
96 result.resize (dvy); | |
97 | |
98 for (int i = 0; i < nelx; i++) | |
99 if (is_scalar_op) | |
100 for (int k = 0; k < nely; k++) | |
101 result(i+k) = op (x(i), y(k)); | |
102 else | |
103 result(i) = op (x(i), y(i)); | |
104 | |
105 retval = result; | |
106 } | |
107 else | |
108 error ("%s: size of X and Y must match, or one operand must be a scalar", | |
109 fname.c_str ()); | |
110 | |
111 return retval; | |
112 } | |
113 | |
114 // Trampoline function, instantiates the proper template above, with | |
115 // reflective information hardwired. We can't hardwire this information | |
116 // in Fbitxxx DEFUNs below, because at that moment, we still don't have | |
117 // information about which integer types we need to instantiate. | |
118 template<typename T> | |
119 octave_value | |
120 bitopx (const std::string& fname, const Array<T>& x, const Array<T>& y) | |
121 { | |
122 if (fname == "bitand") | |
123 return bitopxx (std::bit_and<T>(), fname, x, y); | |
124 if (fname == "bitor") | |
125 return bitopxx (std::bit_or<T>(), fname, x, y); | |
126 | |
127 //else (fname == "bitxor") | |
128 return bitopxx (std::bit_xor<T>(), fname, x, y); | |
129 } | |
130 | |
131 octave_value | |
132 bitop (const std::string& fname, const octave_value_list& args) | |
133 { | |
134 octave_value retval; | |
135 | |
136 int nargin = args.length (); | |
137 | |
138 if (nargin == 2) | |
139 { | |
140 if ((args(0).class_name () == octave_scalar::static_class_name ()) | |
141 || (args(0).class_name () == octave_bool::static_class_name ()) | |
142 || (args(1).class_name () == octave_scalar::static_class_name ()) | |
143 || (args(1).class_name () == octave_bool::static_class_name ())) | |
144 { | |
145 bool arg0_is_int = (args(0).class_name () != | |
146 octave_scalar::static_class_name () && | |
147 args(0).class_name () != | |
148 octave_bool::static_class_name ()); | |
149 bool arg1_is_int = (args(1).class_name () != | |
150 octave_scalar::static_class_name () && | |
151 args(1).class_name () != | |
152 octave_bool::static_class_name ()); | |
153 | |
154 if (! (arg0_is_int || arg1_is_int)) | |
155 { | |
156 uint64NDArray x (args(0).array_value ()); | |
157 uint64NDArray y (args(1).array_value ()); | |
158 if (! error_state) | |
159 retval = bitopx (fname, x, y).array_value (); | |
160 } | |
161 else | |
162 { | |
163 int p = (arg0_is_int ? 1 : 0); | |
164 int q = (arg0_is_int ? 0 : 1); | |
165 | |
166 NDArray dx = args(p).array_value (); | |
167 | |
168 if (args(q).type_id () == octave_uint64_matrix::static_type_id () | |
169 || args(q).type_id () == octave_uint64_scalar::static_type_id ()) | |
170 { | |
171 uint64NDArray x (dx); | |
172 uint64NDArray y = args(q).uint64_array_value (); | |
173 if (! error_state) | |
174 retval = bitopx (fname, x, y); | |
175 } | |
176 else if (args(q).type_id () == octave_uint32_matrix::static_type_id () | |
177 || args(q).type_id () == octave_uint32_scalar::static_type_id ()) | |
178 { | |
179 uint32NDArray x (dx); | |
180 uint32NDArray y = args(q).uint32_array_value (); | |
181 if (! error_state) | |
182 retval = bitopx (fname, x, y); | |
183 } | |
184 else if (args(q).type_id () == octave_uint16_matrix::static_type_id () | |
185 || args(q).type_id () == octave_uint16_scalar::static_type_id ()) | |
186 { | |
187 uint16NDArray x (dx); | |
188 uint16NDArray y = args(q).uint16_array_value (); | |
189 if (! error_state) | |
190 retval = bitopx (fname, x, y); | |
191 } | |
192 else if (args(q).type_id () == octave_uint8_matrix::static_type_id () | |
193 || args(q).type_id () == octave_uint8_scalar::static_type_id ()) | |
194 { | |
195 uint8NDArray x (dx); | |
196 uint8NDArray y = args(q).uint8_array_value (); | |
197 if (! error_state) | |
198 retval = bitopx (fname, x, y); | |
199 } | |
200 else if (args(q).type_id () == octave_int64_matrix::static_type_id () | |
201 || args(q).type_id () == octave_int64_scalar::static_type_id ()) | |
202 { | |
203 int64NDArray x (dx); | |
204 int64NDArray y = args(q).int64_array_value (); | |
205 if (! error_state) | |
206 retval = bitopx (fname, x, y); | |
207 } | |
208 else if (args(q).type_id () == octave_int32_matrix::static_type_id () | |
209 || args(q).type_id () == octave_int32_scalar::static_type_id ()) | |
210 { | |
211 int32NDArray x (dx); | |
212 int32NDArray y = args(q).int32_array_value (); | |
213 if (! error_state) | |
214 retval = bitopx (fname, x, y); | |
215 } | |
216 else if (args(q).type_id () == octave_int16_matrix::static_type_id () | |
217 || args(q).type_id () == octave_int16_scalar::static_type_id ()) | |
218 { | |
219 int16NDArray x (dx); | |
220 int16NDArray y = args(q).int16_array_value (); | |
221 if (! error_state) | |
222 retval = bitopx (fname, x, y); | |
223 } | |
224 else if (args(q).type_id () == octave_int8_matrix::static_type_id () | |
225 || args(q).type_id () == octave_int8_scalar::static_type_id ()) | |
226 { | |
227 int8NDArray x (dx); | |
228 int8NDArray y = args(q).int8_array_value (); | |
229 if (! error_state) | |
230 retval = bitopx (fname, x, y); | |
231 } | |
232 else | |
233 error ("%s: invalid operand type", fname.c_str ()); | |
234 } | |
235 } | |
236 else if (args(0).class_name () == args(1).class_name ()) | |
237 { | |
238 if (args(0).type_id () == octave_uint64_matrix::static_type_id () | |
239 || args(0).type_id () == octave_uint64_scalar::static_type_id ()) | |
240 { | |
241 uint64NDArray x = args(0).uint64_array_value (); | |
242 uint64NDArray y = args(1).uint64_array_value (); | |
243 if (! error_state) | |
244 retval = bitopx (fname, x, y); | |
245 } | |
246 else if (args(0).type_id () == octave_uint32_matrix::static_type_id () | |
247 || args(0).type_id () == octave_uint32_scalar::static_type_id ()) | |
248 { | |
249 uint32NDArray x = args(0).uint32_array_value (); | |
250 uint32NDArray y = args(1).uint32_array_value (); | |
251 if (! error_state) | |
252 retval = bitopx (fname, x, y); | |
253 } | |
254 else if (args(0).type_id () == octave_uint16_matrix::static_type_id () | |
255 || args(0).type_id () == octave_uint16_scalar::static_type_id ()) | |
256 { | |
257 uint16NDArray x = args(0).uint16_array_value (); | |
258 uint16NDArray y = args(1).uint16_array_value (); | |
259 if (! error_state) | |
260 retval = bitopx (fname, x, y); | |
261 } | |
262 else if (args(0).type_id () == octave_uint8_matrix::static_type_id () | |
263 || args(0).type_id () == octave_uint8_scalar::static_type_id ()) | |
264 { | |
265 uint8NDArray x = args(0).uint8_array_value (); | |
266 uint8NDArray y = args(1).uint8_array_value (); | |
267 if (! error_state) | |
268 retval = bitopx (fname, x, y); | |
269 } | |
270 else if (args(0).type_id () == octave_int64_matrix::static_type_id () | |
271 || args(0).type_id () == octave_int64_scalar::static_type_id ()) | |
272 { | |
273 int64NDArray x = args(0).int64_array_value (); | |
274 int64NDArray y = args(1).int64_array_value (); | |
275 if (! error_state) | |
276 retval = bitopx (fname, x, y); | |
277 } | |
278 else if (args(0).type_id () == octave_int32_matrix::static_type_id () | |
279 || args(0).type_id () == octave_int32_scalar::static_type_id ()) | |
280 { | |
281 int32NDArray x = args(0).int32_array_value (); | |
282 int32NDArray y = args(1).int32_array_value (); | |
283 if (! error_state) | |
284 retval = bitopx (fname, x, y); | |
285 } | |
286 else if (args(0).type_id () == octave_int16_matrix::static_type_id () | |
287 || args(0).type_id () == octave_int16_scalar::static_type_id ()) | |
288 { | |
289 int16NDArray x = args(0).int16_array_value (); | |
290 int16NDArray y = args(1).int16_array_value (); | |
291 if (! error_state) | |
292 retval = bitopx (fname, x, y); | |
293 } | |
294 else if (args(0).type_id () == octave_int8_matrix::static_type_id () | |
295 || args(0).type_id () == octave_int8_scalar::static_type_id ()) | |
296 { | |
297 int8NDArray x = args(0).int8_array_value (); | |
298 int8NDArray y = args(1).int8_array_value (); | |
299 if (! error_state) | |
300 retval = bitopx (fname, x, y); | |
301 } | |
302 else | |
303 error ("%s: invalid operand type", fname.c_str ()); | |
304 } | |
305 else | |
306 error ("%s: must have matching operand types", fname.c_str ()); | |
307 } | |
308 else | |
309 print_usage (); | |
310 | |
311 return retval; | |
312 } | |
313 | |
314 DEFUN (bitand, args, , | |
315 "-*- texinfo -*-\n\ | |
316 @deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})\n\ | |
317 Return the bitwise AND of non-negative integers.\n\ | |
318 @var{x}, @var{y} must be in the range [0,bitmax]\n\ | |
319 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ | |
320 @end deftypefn") | |
321 { | |
322 return bitop ("bitand", args); | |
323 } | |
324 | |
325 DEFUN (bitor, args, , | |
326 "-*- texinfo -*-\n\ | |
327 @deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})\n\ | |
328 Return the bitwise OR of non-negative integers.\n\ | |
329 @var{x}, @var{y} must be in the range [0,bitmax]\n\ | |
330 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ | |
331 @end deftypefn") | |
332 { | |
333 return bitop ("bitor", args); | |
334 } | |
335 | |
336 DEFUN (bitxor, args, , | |
337 "-*- texinfo -*-\n\ | |
338 @deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})\n\ | |
339 Return the bitwise XOR of non-negative integers.\n\ | |
340 @var{x}, @var{y} must be in the range [0,bitmax]\n\ | |
341 @seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}\n\ | |
342 @end deftypefn") | |
343 { | |
344 return bitop ("bitxor", args); | |
345 } | |
346 | |
347 static int64_t | |
348 bitshift (double a, int n, int64_t mask) | |
349 { | |
350 // In the name of bug-for-bug compatibility. | |
351 if (a < 0) | |
352 return -bitshift (-a, n, mask); | |
353 | |
354 if (n > 0) | |
355 return (static_cast<int64_t> (a) << n) & mask; | |
356 else if (n < 0) | |
357 return (static_cast<int64_t> (a) >> -n) & mask; | |
358 else | |
359 return static_cast<int64_t> (a) & mask; | |
360 } | |
361 | |
362 static int64_t | |
363 bitshift (float a, int n, int64_t mask) | |
364 { | |
365 // In the name of bug-for-bug compatibility. | |
366 if (a < 0) | |
367 return -bitshift (-a, n, mask); | |
368 | |
369 if (n > 0) | |
370 return (static_cast<int64_t> (a) << n) & mask; | |
371 else if (n < 0) | |
372 return (static_cast<int64_t> (a) >> -n) & mask; | |
373 else | |
374 return static_cast<int64_t> (a) & mask; | |
375 } | |
376 | |
377 // Note that the bitshift operators are undefined if shifted by more | |
378 // bits than in the type, so we need to test for the size of the | |
379 // shift. | |
380 | |
381 #define DO_BITSHIFT(T) \ | |
382 if (! error_state) \ | |
383 { \ | |
384 double d1, d2; \ | |
385 \ | |
386 if (n.all_integers (d1, d2)) \ | |
387 { \ | |
388 int m_nel = m.numel (); \ | |
389 int n_nel = n.numel (); \ | |
390 \ | |
391 bool is_scalar_op = (m_nel == 1 || n_nel == 1); \ | |
392 \ | |
393 dim_vector m_dv = m.dims (); \ | |
394 dim_vector n_dv = n.dims (); \ | |
395 \ | |
396 bool is_array_op = (m_dv == n_dv); \ | |
397 \ | |
398 if (is_array_op || is_scalar_op) \ | |
399 { \ | |
400 T ## NDArray result; \ | |
401 \ | |
402 if (m_nel != 1) \ | |
403 result.resize (m_dv); \ | |
404 else \ | |
405 result.resize (n_dv); \ | |
406 \ | |
407 for (int i = 0; i < m_nel; i++) \ | |
408 if (is_scalar_op) \ | |
409 for (int k = 0; k < n_nel; k++) \ | |
410 if (static_cast<int> (n(k)) >= bits_in_type) \ | |
411 result(i+k) = 0; \ | |
412 else \ | |
413 result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \ | |
414 else \ | |
415 if (static_cast<int> (n(i)) >= bits_in_type) \ | |
416 result(i) = 0; \ | |
417 else \ | |
418 result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \ | |
419 \ | |
420 retval = result; \ | |
421 } \ | |
422 else \ | |
423 error ("bitshift: size of A and N must match, or one operand must be a scalar"); \ | |
424 } \ | |
425 else \ | |
426 error ("bitshift: expecting integer as second argument"); \ | |
427 } | |
428 | |
429 #define DO_UBITSHIFT(T, N) \ | |
430 do \ | |
431 { \ | |
432 int bits_in_type = octave_ ## T :: nbits (); \ | |
433 T ## NDArray m = m_arg.T ## _array_value (); \ | |
434 octave_ ## T mask = octave_ ## T::max (); \ | |
435 if ((N) < bits_in_type) \ | |
436 mask = bitshift (mask, (N) - bits_in_type); \ | |
437 else if ((N) < 1) \ | |
438 mask = 0; \ | |
439 DO_BITSHIFT (T); \ | |
440 } \ | |
441 while (0) | |
442 | |
443 #define DO_SBITSHIFT(T, N) \ | |
444 do \ | |
445 { \ | |
446 int bits_in_type = octave_ ## T :: nbits (); \ | |
447 T ## NDArray m = m_arg.T ## _array_value (); \ | |
448 octave_ ## T mask = octave_ ## T::max (); \ | |
449 if ((N) < bits_in_type) \ | |
450 mask = bitshift (mask, (N) - bits_in_type); \ | |
451 else if ((N) < 1) \ | |
452 mask = 0; \ | |
453 mask = mask | octave_ ## T :: min (); /* FIXME: 2's complement only? */ \ | |
454 DO_BITSHIFT (T); \ | |
455 } \ | |
456 while (0) | |
457 | |
458 DEFUN (bitshift, args, , | |
459 "-*- texinfo -*-\n\ | |
460 @deftypefn {Built-in Function} {} bitshift (@var{a}, @var{k})\n\ | |
461 @deftypefnx {Built-in Function} {} bitshift (@var{a}, @var{k}, @var{n})\n\ | |
462 Return a @var{k} bit shift of @var{n}-digit unsigned\n\ | |
463 integers in @var{a}. A positive @var{k} leads to a left shift;\n\ | |
464 A negative value to a right shift. If @var{n} is omitted it defaults\n\ | |
465 to log2(bitmax)+1.\n\ | |
466 @var{n} must be in the range [1,log2(bitmax)+1] usually [1,33].\n\ | |
467 \n\ | |
468 @example\n\ | |
469 @group\n\ | |
470 bitshift (eye (3), 1)\n\ | |
471 @result{}\n\ | |
472 @group\n\ | |
473 2 0 0\n\ | |
474 0 2 0\n\ | |
475 0 0 2\n\ | |
476 @end group\n\ | |
477 \n\ | |
478 bitshift (10, [-2, -1, 0, 1, 2])\n\ | |
479 @result{} 2 5 10 20 40\n\ | |
480 @c FIXME -- restore this example when third arg is allowed to be an array.\n\ | |
481 @c\n\ | |
482 @c\n\ | |
483 @c bitshift ([1, 10], 2, [3,4])\n\ | |
484 @c @result{} 4 8\n\ | |
485 @end group\n\ | |
486 @end example\n\ | |
487 @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitmax}\n\ | |
488 @end deftypefn") | |
489 { | |
490 octave_value retval; | |
491 | |
492 int nargin = args.length (); | |
493 | |
494 if (nargin == 2 || nargin == 3) | |
495 { | |
496 int nbits = 64; | |
497 | |
498 NDArray n = args(1).array_value (); | |
499 | |
500 if (error_state) | |
501 error ("bitshift: expecting integer as second argument"); | |
502 else | |
503 { | |
504 if (nargin == 3) | |
505 { | |
506 // FIXME -- for compatibility, we should accept an array | |
507 // or a scalar as the third argument. | |
508 if (args(2).numel () > 1) | |
509 error ("bitshift: N must be a scalar integer"); | |
510 else | |
511 { | |
512 nbits = args(2).int_value (); | |
513 | |
514 if (error_state) | |
515 error ("bitshift: N must be an integer"); | |
516 else if (nbits < 0) | |
517 error ("bitshift: N must be positive"); | |
518 } | |
519 } | |
520 } | |
521 | |
522 if (error_state) | |
523 return retval; | |
524 | |
525 octave_value m_arg = args(0); | |
526 std::string cname = m_arg.class_name (); | |
527 | |
528 if (cname == "uint8") | |
529 DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8); | |
530 else if (cname == "uint16") | |
531 DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16); | |
532 else if (cname == "uint32") | |
533 DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32); | |
534 else if (cname == "uint64") | |
535 DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64); | |
536 else if (cname == "int8") | |
537 DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8); | |
538 else if (cname == "int16") | |
539 DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16); | |
540 else if (cname == "int32") | |
541 DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32); | |
542 else if (cname == "int64") | |
543 DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64); | |
544 else if (cname == "double") | |
545 { | |
546 nbits = (nbits < 53 ? nbits : 53); | |
547 int64_t mask = 0x1FFFFFFFFFFFFFLL; | |
548 if (nbits < 53) | |
549 mask = mask >> (53 - nbits); | |
550 else if (nbits < 1) | |
551 mask = 0; | |
552 int bits_in_type = 64; | |
553 NDArray m = m_arg.array_value (); | |
554 DO_BITSHIFT ( ); | |
555 } | |
556 else | |
557 error ("bitshift: not defined for %s objects", cname.c_str ()); | |
558 } | |
559 else | |
560 print_usage (); | |
561 | |
562 return retval; | |
563 } | |
564 | |
565 DEFUN (bitmax, args, , | |
566 "-*- texinfo -*-\n\ | |
567 @deftypefn {Built-in Function} {} bitmax ()\n\ | |
568 @deftypefnx {Built-in Function} {} bitmax (\"double\")\n\ | |
569 @deftypefnx {Built-in Function} {} bitmax (\"single\")\n\ | |
570 Return the largest integer that can be represented within a floating point\n\ | |
571 value. The default class is \"double\", but \"single\" is a valid option.\n\ | |
572 On IEEE-754 compatible systems, @code{bitmax} is @w{@math{2^{53} - 1}}.\n\ | |
573 @end deftypefn") | |
574 { | |
575 octave_value retval; | |
576 std::string cname = "double"; | |
577 int nargin = args.length (); | |
578 | |
579 if (nargin == 1 && args(0).is_string ()) | |
580 cname = args(0).string_value (); | |
581 else if (nargin != 0) | |
582 { | |
583 print_usage (); | |
584 return retval; | |
585 } | |
586 | |
587 if (cname == "double") | |
588 retval = (static_cast<double> (0x1FFFFFFFFFFFFFLL)); | |
589 else if (cname == "single") | |
590 retval = (static_cast<double> (0xFFFFFFL)); | |
591 else | |
592 error ("bitmax: not defined for class '%s'", cname.c_str ()); | |
593 | |
594 return retval; | |
595 } | |
596 | |
597 DEFUN (intmax, args, , | |
598 "-*- texinfo -*-\n\ | |
599 @deftypefn {Built-in Function} {} intmax (@var{type})\n\ | |
600 Return the largest integer that can be represented in an integer type.\n\ | |
601 The variable @var{type} can be\n\ | |
602 \n\ | |
603 @table @code\n\ | |
604 @item int8\n\ | |
605 signed 8-bit integer.\n\ | |
606 \n\ | |
607 @item int16\n\ | |
608 signed 16-bit integer.\n\ | |
609 \n\ | |
610 @item int32\n\ | |
611 signed 32-bit integer.\n\ | |
612 \n\ | |
613 @item int64\n\ | |
614 signed 64-bit integer.\n\ | |
615 \n\ | |
616 @item uint8\n\ | |
617 unsigned 8-bit integer.\n\ | |
618 \n\ | |
619 @item uint16\n\ | |
620 unsigned 16-bit integer.\n\ | |
621 \n\ | |
622 @item uint32\n\ | |
623 unsigned 32-bit integer.\n\ | |
624 \n\ | |
625 @item uint64\n\ | |
626 unsigned 64-bit integer.\n\ | |
627 @end table\n\ | |
628 \n\ | |
629 The default for @var{type} is @code{uint32}.\n\ | |
630 @seealso{intmin, bitmax}\n\ | |
631 @end deftypefn") | |
632 { | |
633 octave_value retval; | |
634 std::string cname = "int32"; | |
635 int nargin = args.length (); | |
636 | |
637 if (nargin == 1 && args(0).is_string ()) | |
638 cname = args(0).string_value (); | |
639 else if (nargin != 0) | |
640 { | |
641 print_usage (); | |
642 return retval; | |
643 } | |
644 | |
645 if (cname == "uint8") | |
646 retval = octave_uint8 (std::numeric_limits<uint8_t>::max ()); | |
647 else if (cname == "uint16") | |
648 retval = octave_uint16 (std::numeric_limits<uint16_t>::max ()); | |
649 else if (cname == "uint32") | |
650 retval = octave_uint32 (std::numeric_limits<uint32_t>::max ()); | |
651 else if (cname == "uint64") | |
652 retval = octave_uint64 (std::numeric_limits<uint64_t>::max ()); | |
653 else if (cname == "int8") | |
654 retval = octave_int8 (std::numeric_limits<int8_t>::max ()); | |
655 else if (cname == "int16") | |
656 retval = octave_int16 (std::numeric_limits<int16_t>::max ()); | |
657 else if (cname == "int32") | |
658 retval = octave_int32 (std::numeric_limits<int32_t>::max ()); | |
659 else if (cname == "int64") | |
660 retval = octave_int64 (std::numeric_limits<int64_t>::max ()); | |
661 else | |
662 error ("intmax: not defined for '%s' objects", cname.c_str ()); | |
663 | |
664 return retval; | |
665 } | |
666 | |
667 DEFUN (intmin, args, , | |
668 "-*- texinfo -*-\n\ | |
669 @deftypefn {Built-in Function} {} intmin (@var{type})\n\ | |
670 Return the smallest integer that can be represented in an integer type.\n\ | |
671 The variable @var{type} can be\n\ | |
672 \n\ | |
673 @table @code\n\ | |
674 @item int8\n\ | |
675 signed 8-bit integer.\n\ | |
676 \n\ | |
677 @item int16\n\ | |
678 signed 16-bit integer.\n\ | |
679 \n\ | |
680 @item int32\n\ | |
681 signed 32-bit integer.\n\ | |
682 \n\ | |
683 @item int64\n\ | |
684 signed 64-bit integer.\n\ | |
685 \n\ | |
686 @item uint8\n\ | |
687 unsigned 8-bit integer.\n\ | |
688 \n\ | |
689 @item uint16\n\ | |
690 unsigned 16-bit integer.\n\ | |
691 \n\ | |
692 @item uint32\n\ | |
693 unsigned 32-bit integer.\n\ | |
694 \n\ | |
695 @item uint64\n\ | |
696 unsigned 64-bit integer.\n\ | |
697 @end table\n\ | |
698 \n\ | |
699 The default for @var{type} is @code{uint32}.\n\ | |
700 @seealso{intmax, bitmax}\n\ | |
701 @end deftypefn") | |
702 { | |
703 octave_value retval; | |
704 std::string cname = "int32"; | |
705 int nargin = args.length (); | |
706 | |
707 if (nargin == 1 && args(0).is_string ()) | |
708 cname = args(0).string_value (); | |
709 else if (nargin != 0) | |
710 { | |
711 print_usage (); | |
712 return retval; | |
713 } | |
714 | |
715 if (cname == "uint8") | |
716 retval = octave_uint8 (std::numeric_limits<uint8_t>::min ()); | |
717 else if (cname == "uint16") | |
718 retval = octave_uint16 (std::numeric_limits<uint16_t>::min ()); | |
719 else if (cname == "uint32") | |
720 retval = octave_uint32 (std::numeric_limits<uint32_t>::min ()); | |
721 else if (cname == "uint64") | |
722 retval = octave_uint64 (std::numeric_limits<uint64_t>::min ()); | |
723 else if (cname == "int8") | |
724 retval = octave_int8 (std::numeric_limits<int8_t>::min ()); | |
725 else if (cname == "int16") | |
726 retval = octave_int16 (std::numeric_limits<int16_t>::min ()); | |
727 else if (cname == "int32") | |
728 retval = octave_int32 (std::numeric_limits<int32_t>::min ()); | |
729 else if (cname == "int64") | |
730 retval = octave_int64 (std::numeric_limits<int64_t>::min ()); | |
731 else | |
732 error ("intmin: not defined for '%s' objects", cname.c_str ()); | |
733 | |
734 return retval; | |
735 } | |
736 | |
737 DEFUN (sizemax, args, , | |
738 "-*- texinfo -*-\n\ | |
739 @deftypefn {Built-in Function} {} sizemax ()\n\ | |
740 Return the largest value allowed for the size of an array.\n\ | |
741 If Octave is compiled with 64-bit indexing, the result is of class int64,\n\ | |
742 otherwise it is of class int32. The maximum array size is slightly\n\ | |
743 smaller than the maximum value allowable for the relevant class as reported\n\ | |
744 by @code{intmax}.\n\ | |
745 @seealso{intmax}\n\ | |
746 @end deftypefn") | |
747 { | |
748 octave_value retval; | |
749 | |
750 if (args.length () == 0) | |
751 retval = octave_int<octave_idx_type> (dim_vector::dim_max ()); | |
752 else | |
753 print_usage (); | |
754 | |
755 return retval; | |
756 } |