GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
oct-inttypes.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2017 John W. Eaton
4 Copyright (C) 2008-2009 Jaroslav Hajek
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include "fpucw-wrappers.h"
29 #include "lo-error.h"
30 #include "oct-inttypes.h"
31 
32 template <typename T>
33 const octave_int<T> octave_int<T>::zero (static_cast<T> (0));
34 
35 template <typename T>
36 const octave_int<T> octave_int<T>::one (static_cast<T> (1));
37 
38 // define type names.
39 #define DECLARE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME) \
40  template <> \
41  OCTAVE_API const char * \
42  octave_int<TYPE>::type_name () { return TYPENAME; }
43 
48 DECLARE_OCTAVE_INT_TYPENAME (uint8_t, "uint8")
51 DECLARE_OCTAVE_INT_TYPENAME (uint64_t, "uint64")
52 
53 template <class T>
54 template <class S>
55 T
57 {
58  // Compute proper thresholds.
59  static const S thmin = compute_threshold (static_cast<S> (min_val ()),
60  min_val ());
61  static const S thmax = compute_threshold (static_cast<S> (max_val ()),
62  max_val ());
63  if (octave::math::isnan (value))
64  {
65  return static_cast<T> (0);
66  }
67  else if (value < thmin)
68  {
69  return min_val ();
70  }
71  else if (value > thmax)
72  {
73  return max_val ();
74  }
75  else
76  {
77  S rvalue = octave::math::round (value);
78  return static_cast<T> (rvalue);
79  }
80 }
81 
82 #define INSTANTIATE_CONVERT_REAL_1(T, S) \
83  template \
84  OCTAVE_API \
85  T \
86  octave_int_base<T>::convert_real (const S&)
87 
88 #define INSTANTIATE_CONVERT_REAL(S) \
89  INSTANTIATE_CONVERT_REAL_1 (int8_t, S); \
90  INSTANTIATE_CONVERT_REAL_1 (uint8_t, S); \
91  INSTANTIATE_CONVERT_REAL_1 (int16_t, S); \
92  INSTANTIATE_CONVERT_REAL_1 (uint16_t, S); \
93  INSTANTIATE_CONVERT_REAL_1 (int32_t, S); \
94  INSTANTIATE_CONVERT_REAL_1 (uint32_t, S); \
95  INSTANTIATE_CONVERT_REAL_1 (int64_t, S); \
96  INSTANTIATE_CONVERT_REAL_1 (uint64_t, S)
97 
100 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
101 INSTANTIATE_CONVERT_REAL (long double);
102 #endif
103 
104 #if defined (OCTAVE_INT_USE_LONG_DOUBLE)
105 
106 #if defined (OCTAVE_ENSURE_LONG_DOUBLE_OPERATIONS_ARE_NOT_TRUNCATED)
107 
108 #define DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES(T) \
109  template <typename xop> \
110  bool \
111  octave_int_cmp_op::external_mop (double x, T y) \
112  { \
113  unsigned int oldcw = octave_begin_long_double_rounding (); \
114  \
115  bool retval = xop::op (static_cast<long double> (x), \
116  static_cast<long double> (y)); \
117  \
118  octave_end_long_double_rounding (oldcw); \
119  \
120  return retval; \
121  } \
122  \
123  template <typename xop> \
124  bool \
125  octave_int_cmp_op::external_mop (T x, double y) \
126  { \
127  unsigned int oldcw = octave_begin_long_double_rounding (); \
128  \
129  bool retval = xop::op (static_cast<long double> (x), \
130  static_cast<long double> (y)); \
131  \
132  octave_end_long_double_rounding (oldcw); \
133  \
134  return retval; \
135  }
136 
137 DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (int64_t)
138 DEFINE_OCTAVE_LONG_DOUBLE_CMP_OP_TEMPLATES (uint64_t)
139 
140 #define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP(OP, T) \
141  template OCTAVE_API bool \
142  octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (double, T); \
143  template OCTAVE_API bool \
144  octave_int_cmp_op::external_mop<octave_int_cmp_op::OP> (T, double)
145 
146 #define INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS(T) \
147  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (lt, T); \
148  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (le, T); \
149  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (gt, T); \
150  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ge, T); \
151  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (eq, T); \
152  INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OP (ne, T)
153 
154 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (int64_t);
155 INSTANTIATE_LONG_DOUBLE_LONG_DOUBLE_CMP_OPS (uint64_t);
156 
157 uint64_t
158 octave_external_uint64_uint64_mul (uint64_t x, uint64_t y)
159 {
160  unsigned int oldcw = octave_begin_long_double_rounding ();
161 
163 
165 
166  return retval;
167 }
168 
169 int64_t
170 octave_external_int64_int64_mul (int64_t x, int64_t y)
171 {
172  unsigned int oldcw = octave_begin_long_double_rounding ();
173 
175 
177 
178  return retval;
179 }
180 
181 // Note that if we return long double it is apparently possible for
182 // truncation to happen at the point of storing the result in retval,
183 // which can happen after we end long double rounding. Attempt to avoid
184 // that problem by storing the full precision temporary value in the
185 // integer value before we end the long double rounding mode.
186 // Similarly, the conversion from the 64-bit integer type to long double
187 // must also occur in long double rounding mode.
188 
189 #define OCTAVE_LONG_DOUBLE_OP(T, OP, NAME) \
190  T \
191  external_double_ ## T ## _ ## NAME (double x, T y) \
192  { \
193  unsigned int oldcw = octave_begin_long_double_rounding (); \
194  \
195  T retval = T (x OP static_cast<long double> (y.value ())); \
196  \
197  octave_end_long_double_rounding (oldcw); \
198  \
199  return retval; \
200  } \
201  \
202  T \
203  external_ ## T ## _double_ ## NAME (T x, double y) \
204  { \
205  unsigned int oldcw = octave_begin_long_double_rounding (); \
206  \
207  T retval = T (static_cast<long double> (x.value ()) OP y); \
208  \
209  octave_end_long_double_rounding (oldcw); \
210  \
211  return retval; \
212  }
213 
214 #define OCTAVE_LONG_DOUBLE_OPS(T) \
215  OCTAVE_LONG_DOUBLE_OP (T, +, add); \
216  OCTAVE_LONG_DOUBLE_OP (T, -, sub); \
217  OCTAVE_LONG_DOUBLE_OP (T, *, mul); \
218  OCTAVE_LONG_DOUBLE_OP (T, /, div)
219 
220 OCTAVE_LONG_DOUBLE_OPS(octave_int64);
221 OCTAVE_LONG_DOUBLE_OPS(octave_uint64);
222 
223 #endif
224 
225 #else
226 
227 // Define comparison operators
228 
229 template <typename xop>
230 bool
232 {
233  static const double xxup = std::numeric_limits<uint64_t>::max ();
234  // This converts to the nearest double. Unless there's an equality, the
235  // result is clear.
236  double xx = x;
237  if (xx != y)
238  return xop::op (xx, y);
239  else
240  {
241  // If equality occurred we compare as integers.
242  if (xx == xxup)
243  return xop::gtval;
244  else
245  return xop::op (x, static_cast<uint64_t> (xx));
246  }
247 }
248 
249 template <typename xop>
250 bool
252 {
253  static const double xxup = std::numeric_limits<int64_t>::max ();
254  static const double xxlo = std::numeric_limits<int64_t>::min ();
255  // This converts to the nearest double. Unless there's an equality, the
256  // result is clear.
257  double xx = x;
258  if (xx != y)
259  return xop::op (xx, y);
260  else
261  {
262  // If equality occurred we compare as integers.
263  if (xx == xxup)
264  return xop::gtval;
265  else if (xx == xxlo)
266  return xop::ltval;
267  else
268  return xop::op (x, static_cast<int64_t> (xx));
269  }
270 
271 }
272 
273 // We define double-int operations by reverting the operator
274 
275 // A trait class reverting the operator
276 template <typename xop>
277 class rev_op
278 {
279 public:
280  typedef xop op;
281 };
282 
283 #define DEFINE_REVERTED_OPERATOR(OP1,OP2) \
284  template <> \
285  class rev_op<octave_int_cmp_op::OP1> \
286  { \
287  public: \
288  typedef octave_int_cmp_op::OP2 op; \
289  }
290 
295 
296 template <typename xop>
297 bool
299 {
300  typedef typename rev_op<xop>::op rop;
301  return mop<rop> (y, x);
302 }
303 
304 template <typename xop>
305 bool
307 {
308  typedef typename rev_op<xop>::op rop;
309  return mop<rop> (y, x);
310 }
311 
312 // Define handlers for int64 multiplication
313 
314 template <>
315 uint64_t
317 {
318  // Get upper words
319  uint64_t ux = x >> 32;
320  uint64_t uy = y >> 32;
321  uint64_t res;
322  if (ux)
323  {
324  if (uy)
325  goto overflow;
326  else
327  {
328  uint64_t ly = static_cast<uint32_t> (y);
329  uint64_t uxly = ux*ly;
330  if (uxly >> 32)
331  goto overflow;
332  uxly <<= 32; // never overflows
333  uint64_t lx = static_cast<uint32_t> (x);
334  uint64_t lxly = lx*ly;
335  res = add (uxly, lxly);
336  }
337  }
338  else if (uy)
339  {
340  uint64_t lx = static_cast<uint32_t> (x);
341  uint64_t uylx = uy*lx;
342  if (uylx >> 32)
343  goto overflow;
344  uylx <<= 32; // never overflows
345  uint64_t ly = static_cast<uint32_t> (y);
346  uint64_t lylx = ly*lx;
347  res = add (uylx, lylx);
348  }
349  else
350  {
351  uint64_t lx = static_cast<uint32_t> (x);
352  uint64_t ly = static_cast<uint32_t> (y);
353  res = lx*ly;
354  }
355 
356  return res;
357 
358 overflow:
359  return max_val ();
360 }
361 
362 template <>
363 int64_t
365 {
366  // The signed case is far worse. The problem is that
367  // even if neither integer fits into signed 32-bit range, the result may
368  // still be OK. Uh oh.
369 
370  // Essentially, what we do is compute sign, multiply absolute values
371  // (as above) and impose the sign.
372  // FIXME: can we do something faster if we OCTAVE_HAVE_FAST_INT_OPS?
373 
374  uint64_t usx = octave_int_abs (x);
375  uint64_t usy = octave_int_abs (y);
376  bool positive = (x < 0) == (y < 0);
377 
378  // Get upper words
379  uint64_t ux = usx >> 32;
380  uint64_t uy = usy >> 32;
381  uint64_t res;
382  if (ux)
383  {
384  if (uy)
385  goto overflow;
386  else
387  {
388  uint64_t ly = static_cast<uint32_t> (usy);
389  uint64_t uxly = ux*ly;
390  if (uxly >> 32)
391  goto overflow;
392  uxly <<= 32; // never overflows
393  uint64_t lx = static_cast<uint32_t> (usx);
394  uint64_t lxly = lx*ly;
395  res = uxly + lxly;
396  if (res < uxly)
397  goto overflow;
398  }
399  }
400  else if (uy)
401  {
402  uint64_t lx = static_cast<uint32_t> (usx);
403  uint64_t uylx = uy*lx;
404  if (uylx >> 32)
405  goto overflow;
406  uylx <<= 32; // never overflows
407  uint64_t ly = static_cast<uint32_t> (usy);
408  uint64_t lylx = ly*lx;
409  res = uylx + lylx;
410  if (res < uylx)
411  goto overflow;
412  }
413  else
414  {
415  uint64_t lx = static_cast<uint32_t> (usx);
416  uint64_t ly = static_cast<uint32_t> (usy);
417  res = lx*ly;
418  }
419 
420  if (positive)
421  {
422  if (res > static_cast<uint64_t> (max_val ()))
423  {
424  return max_val ();
425  }
426  else
427  return static_cast<int64_t> (res);
428  }
429  else
430  {
431  if (res > static_cast<uint64_t> (-min_val ()))
432  {
433  return min_val ();
434  }
435  else
436  return -static_cast<int64_t> (res);
437  }
438 
439 overflow:
440  return positive ? max_val () : min_val ();
441 
442 }
443 
444 #define INT_DOUBLE_BINOP_DECL(OP,SUFFIX) \
445  template <> \
446  OCTAVE_API octave_ ## SUFFIX \
447  operator OP (const octave_ ## SUFFIX & x, const double& y)
448 
449 #define DOUBLE_INT_BINOP_DECL(OP,SUFFIX) \
450  template <> \
451  OCTAVE_API octave_ ## SUFFIX \
452  operator OP (const double& x, const octave_ ## SUFFIX & y)
453 
455 {
456  return (y < 0) ? x - octave_uint64 (-y) : x + octave_uint64 (y);
457 }
458 
460 { return y + x; }
461 
463 {
464  if (fabs (y) < static_cast<double> (octave_int64::max ()))
465  return x + octave_int64 (y);
466  else
467  {
468  // If the number is within the int64 range (the most common case,
469  // probably), the above will work as expected. If not, it's more
470  // complicated - as long as y is within _twice_ the signed range, the
471  // result may still be an integer. An instance of such an operation is
472  // 3*2**62 + (1+intmin ('int64')) that should yield int64 (2**62) + 1.
473  // So what we do is to try to convert y/2 and add it twice. Note that
474  // if y/2 overflows, the result must overflow as well, and that y/2
475  // cannot be a fractional number.
476  octave_int64 y2 (y / 2);
477  return (x + y2) + y2;
478  }
479 }
480 
482 {
483  return y + x;
484 }
485 
487 {
488  return x + (-y);
489 }
490 
492 {
493  if (x <= static_cast<double> (octave_uint64::max ()))
494  return octave_uint64 (x) - y;
495  else
496  {
497  // Again a trick to get the corner cases right. Things like
498  // 3**2**63 - intmax ('uint64') should produce the correct result, i.e.
499  // int64 (2**63) + 1.
500  const double p2_64 = std::pow (2.0, 64);
501  if (y.bool_value ())
502  {
503  const uint64_t p2_64my = (~y.value ()) + 1; // Equals 2**64 - y
504  return octave_uint64 (x - p2_64) + octave_uint64 (p2_64my);
505  }
506  else
507  return octave_uint64 (p2_64);
508  }
509 }
510 
512 {
513  return x + (-y);
514 }
515 
517 {
518  static const bool twosc = (std::numeric_limits<int64_t>::min ()
520  // In case of symmetric integers (not two's complement), this will probably
521  // be eliminated at compile time.
522  if (twosc && y.value () == std::numeric_limits<int64_t>::min ())
523  {
524  return octave_int64 (x + std::pow (2.0, 63));
525  }
526  else
527  return x + (-y);
528 }
529 
530 // NOTE:
531 // Emulated mixed multiplications are tricky due to possible precision loss.
532 // Here, after sorting out common cases for speed, we follow the strategy
533 // of converting the double number into the form sign * 64-bit integer *
534 // 2**exponent, multiply the 64-bit integers to get a 128-bit number, split that
535 // number into 32-bit words and form 4 double-valued summands (none of which
536 // loses precision), then convert these into integers and sum them. Though it
537 // is not immediately obvious, this should work even w.r.t. rounding (none of
538 // the summands lose precision).
539 
540 // Multiplies two unsigned 64-bit ints to get a 128-bit number represented
541 // as four 32-bit words.
542 static void
543 umul128 (uint64_t x, uint64_t y, uint32_t w[4])
544 {
545  uint64_t lx = static_cast<uint32_t> (x);
546  uint64_t ux = x >> 32;
547  uint64_t ly = static_cast<uint32_t> (y);
548  uint64_t uy = y >> 32;
549  uint64_t a = lx * ly;
550  w[0] = a; a >>= 32;
551  uint64_t uxly = ux*ly;
552  uint64_t uylx = uy*lx;
553  a += static_cast<uint32_t> (uxly); uxly >>= 32;
554  a += static_cast<uint32_t> (uylx); uylx >>= 32;
555  w[1] = a; a >>= 32;
556  uint64_t uxuy = ux * uy;
557  a += uxly; a += uylx; a += uxuy;
558  w[2] = a; a >>= 32;
559  w[3] = a;
560 }
561 
562 // Splits a double into bool sign, unsigned 64-bit mantissa and int exponent
563 static void
564 dblesplit (double x, bool& sign, uint64_t& mtis, int& exp)
565 {
566  sign = x < 0; x = fabs (x);
567  x = octave::math::frexp (x, &exp);
568  exp -= 52;
569  mtis = static_cast<uint64_t> (ldexp (x, 52));
570 }
571 
572 // Gets a double number from a
573 // 32-bit unsigned integer mantissa, exponent, and sign.
574 static double
575 dbleget (bool sign, uint32_t mtis, int exp)
576 {
577  double x = ldexp (static_cast<double> (mtis), exp);
578  return sign ? -x : x;
579 }
580 
582 {
583  if (y >= 0 && y < octave_uint64::max () && y == octave::math::round (y))
584  {
585  return x * octave_uint64 (static_cast<uint64_t> (y));
586  }
587  else if (y == 0.5)
588  {
589  return x / octave_uint64 (static_cast<uint64_t> (2));
590  }
591  else if (y < 0 || octave::math::isnan (y) || octave::math::isinf (y))
592  {
593  return octave_uint64 (x.value () * y);
594  }
595  else
596  {
597  bool sign;
598  uint64_t my;
599  int e;
600  dblesplit (y, sign, my, e);
601  uint32_t w[4];
602  umul128 (x.value (), my, w);
604  for (short i = 0; i < 4; i++)
605  {
606  res += octave_uint64 (dbleget (sign, w[i], e));
607  e += 32;
608  }
609  return res;
610  }
611 }
612 
614 { return y * x; }
615 
617 {
618  if (fabs (y) < octave_int64::max () && y == octave::math::round (y))
619  {
620  return x * octave_int64 (static_cast<int64_t> (y));
621  }
622  else if (fabs (y) == 0.5)
623  {
624  return x / octave_int64 (static_cast<uint64_t> (4*y));
625  }
626  else if (octave::math::isnan (y) || octave::math::isinf (y))
627  {
628  return octave_int64 (x.value () * y);
629  }
630  else
631  {
632  bool sign;
633  uint64_t my;
634  int e;
635  dblesplit (y, sign, my, e);
636  uint32_t w[4];
637  sign = (sign != (x.value () < 0));
638  umul128 (octave_int_abs (x.value ()), my, w);
640  for (short i = 0; i < 4; i++)
641  {
642  res += octave_int64 (dbleget (sign, w[i], e));
643  e += 32;
644  }
645  return res;
646  }
647 }
648 
650 { return y * x; }
651 
653 {
654  return octave_uint64 (x / static_cast<double> (y));
655 }
656 
658 {
659  return octave_int64 (x / static_cast<double> (y));
660 }
661 
663 {
664  if (y >= 0 && y < octave_uint64::max () && y == octave::math::round (y))
665  {
666  return x / octave_uint64 (y);
667  }
668  else
669  return x * (1.0/y);
670 }
671 
673 {
674  if (fabs (y) < octave_int64::max () && y == octave::math::round (y))
675  {
676  return x / octave_int64 (y);
677  }
678  else
679  return x * (1.0/y);
680 }
681 
682 #define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP,T1,T2) \
683  template OCTAVE_API bool \
684  octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
685 
686 #define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
687  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, int64_t); \
688  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, uint64_t); \
689  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, int64_t, double); \
690  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, uint64_t, double)
691 
698 
699 #endif
700 
701 template <typename T>
704 {
706 
707  octave_int<T> zero = static_cast<T> (0);
708  octave_int<T> one = static_cast<T> (1);
709 
710  if (b == zero || a == one)
711  retval = one;
712  else if (b < zero)
713  {
714  if (a == -one)
715  retval = (b.value () % 2) ? a : one;
716  else
717  retval = zero;
718  }
719  else
720  {
721  octave_int<T> a_val = a;
722  T b_val = b; // no need to do saturation on b
723 
724  retval = a;
725 
726  b_val -= 1;
727 
728  while (b_val != 0)
729  {
730  if (b_val & 1)
731  retval = retval * a_val;
732 
733  b_val = b_val >> 1;
734 
735  if (b_val)
736  a_val = a_val * a_val;
737  }
738  }
739 
740  return retval;
741 }
742 
743 template <typename T>
745 pow (const double& a, const octave_int<T>& b)
746 { return octave_int<T> (pow (a, b.double_value ())); }
747 
748 template <typename T>
750 pow (const octave_int<T>& a, const double& b)
751 {
752  return ((b >= 0 && b < std::numeric_limits<T>::digits
753  && b == octave::math::round (b))
754  ? pow (a, octave_int<T> (static_cast<T> (b)))
755  : octave_int<T> (pow (a.double_value (), b)));
756 }
757 
758 template <typename T>
760 pow (const float& a, const octave_int<T>& b)
761 { return octave_int<T> (pow (a, b.float_value ())); }
762 
763 template <typename T>
765 pow (const octave_int<T>& a, const float& b)
766 {
767  return ((b >= 0 && b < std::numeric_limits<T>::digits
768  && b == octave::math::round (b))
769  ? pow (a, octave_int<T> (static_cast<T> (b)))
770  : octave_int<T> (pow (a.double_value (), static_cast<double> (b))));
771 }
772 
773 // FIXME: Do we really need a differently named single-precision
774 // function integer power function here instead of an overloaded
775 // one?
776 template <typename T>
778 powf (const float& a, const octave_int<T>& b)
779 { return octave_int<T> (pow (a, b.float_value ())); }
780 
781 template <typename T>
783 powf (const octave_int<T>& a, const float& b)
784 {
785  return ((b >= 0 && b < std::numeric_limits<T>::digits
786  && b == octave::math::round (b))
787  ? pow (a, octave_int<T> (static_cast<T> (b)))
788  : octave_int<T> (pow (a.double_value (), static_cast<double> (b))));
789 }
790 
791 #define INSTANTIATE_INTTYPE(T) \
792  template class OCTAVE_API octave_int<T>; \
793  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \
794  template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \
795  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \
796  template OCTAVE_API octave_int<T> pow (const float&, const octave_int<T>&); \
797  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const float&); \
798  template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \
799  template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \
800  template OCTAVE_API octave_int<T> \
801  bitshift (const octave_int<T>&, int, const octave_int<T>&);
802 
807 
812 
813 /*
814 
815 %!assert (intmax ("int64") / intmin ("int64"), int64 (-1))
816 %!assert (intmin ("int64") / int64 (-1), intmax ("int64"))
817 %!assert (int64 (2**63), intmax ("int64"))
818 %!assert (uint64 (2**64), intmax ("uint64"))
819 %!test
820 %! a = 1.9*2^61; b = uint64 (a); b++; assert (b > a);
821 %!test
822 %! a = -1.9*2^61; b = int64 (a); b++; assert (b > a);
823 %!test
824 %! a = int64 (-2**60) + 2; assert (1.25*a == (5*a)/4);
825 %!test
826 %! a = uint64 (2**61) + 2; assert (1.25*a == (5*a)/4);
827 %!assert (int32 (2**31+0.5), intmax ("int32"))
828 %!assert (int32 (-2**31-0.5), intmin ("int32"))
829 %!assert ((int64 (2**62)+1)**1, int64 (2**62)+1)
830 %!assert ((int64 (2**30)+1)**2, int64 (2**60+2**31) + 1)
831 
832 %!assert (uint8 (char (128)), uint8 (128))
833 %!assert (uint8 (char (255)), uint8 (255))
834 %!assert (int8 (char (128)), int8 (128))
835 %!assert (int8 (char (255)), int8 (255))
836 
837 %!assert (uint16 (char (128)), uint16 (128))
838 %!assert (uint16 (char (255)), uint16 (255))
839 %!assert (int16 (char (128)), int16 (128))
840 %!assert (int16 (char (255)), int16 (255))
841 
842 %!assert (uint32 (char (128)), uint32 (128))
843 %!assert (uint32 (char (255)), uint32 (255))
844 %!assert (int32 (char (128)), int32 (128))
845 %!assert (int32 (char (255)), int32 (255))
846 
847 %!assert (uint64 (char (128)), uint64 (128))
848 %!assert (uint64 (char (255)), uint64 (255))
849 %!assert (int64 (char (128)), int64 (128))
850 %!assert (int64 (char (255)), int64 (255))
851 */
octave_int< uint64_t > octave_uint64
static const octave_int one
Definition: oct-inttypes.h:957
OCTAVE_EXPORT octave_value_list uint16
Definition: ov.cc:1258
#define INSTANTIATE_CONVERT_REAL(S)
Definition: oct-inttypes.cc:88
static void umul128(uint64_t x, uint64_t y, uint32_t w[4])
bool isnan(double x)
Definition: lo-mappers.cc:347
#define DOUBLE_INT_BINOP_DECL(OP, SUFFIX)
#define INT_DOUBLE_BINOP_DECL(OP, SUFFIX)
is greater than zero
Definition: load-path.cc:2339
T octave_int_abs(T x)
Definition: oct-inttypes.h:78
static T min_val()
Definition: oct-inttypes.h:295
void octave_end_long_double_rounding(unsigned int oldcw)
static T max_val()
Definition: oct-inttypes.h:296
float float_value(void) const
Definition: oct-inttypes.h:901
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:336
i e
Definition: data.cc:2724
double round(double x)
Definition: lo-mappers.cc:333
double double_value(void) const
Definition: oct-inttypes.h:899
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
#define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP)
octave_int< T > powf(const float &a, const octave_int< T > &b)
static S compute_threshold(S val, T orig_val)
Definition: oct-inttypes.h:340
OCTAVE_EXPORT octave_value_list uint32
Definition: ov.cc:1258
std::complex< double > w(std::complex< double > z, double relerr=0)
OCTAVE_EXPORT octave_value_list int16
Definition: ov.cc:1302
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
octave_value retval
Definition: data.cc:6294
OCTAVE_EXPORT octave_value_list int32
Definition: ov.cc:1258
static OCTAVE_API bool emulate_mop(double, int64_t)
#define DEFINE_REVERTED_OPERATOR(OP1, OP2)
static octave_int< T > max(void)
Definition: oct-inttypes.h:948
static const octave_int zero
Definition: oct-inttypes.h:957
bool isinf(double x)
Definition: lo-mappers.cc:387
OCTAVE_EXPORT octave_value_list int64
Definition: ov.cc:1258
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
octave_int< int64_t > octave_int64
the element is set to zero In other the statement xample y
Definition: data.cc:5342
static double dbleget(bool sign, uint32_t mtis, int exp)
b
Definition: cellfun.cc:398
#define INSTANTIATE_INTTYPE(T)
static void dblesplit(double x, bool &sign, uint64_t &mtis, int &exp)
static T convert_real(const S &value)
Definition: oct-inttypes.cc:56
T value(void) const
Definition: oct-inttypes.h:888
uint64_t mul_internal(uint64_t x, uint64_t y)
unsigned int octave_begin_long_double_rounding(void)
#define DECLARE_OCTAVE_INT_TYPENAME(TYPE, TYPENAME)
Definition: oct-inttypes.cc:39
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:205