GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
oct-inttypes.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2018 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
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License 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 <https://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 
45 DECLARE_OCTAVE_INT_TYPENAME (int16_t, "int16")
46 DECLARE_OCTAVE_INT_TYPENAME (int32_t, "int32")
47 DECLARE_OCTAVE_INT_TYPENAME (int64_t, "int64")
48 DECLARE_OCTAVE_INT_TYPENAME (uint8_t, "uint8")
49 DECLARE_OCTAVE_INT_TYPENAME (uint16_t, "uint16")
50 DECLARE_OCTAVE_INT_TYPENAME (uint32_t, "uint32")
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 ());
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 (u)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 even if neither
367  // integer fits into signed 32-bit range, the result may still be OK.
368  // Uh oh.
369 
370  // Essentially, what we do is compute sign, multiply absolute values
371  // (as above) and impose the sign.
372 
373  uint64_t usx = octave_int_abs (x);
374  uint64_t usy = octave_int_abs (y);
375  bool positive = (x < 0) == (y < 0);
376 
377  // Get upper words
378  uint64_t ux = usx >> 32;
379  uint64_t uy = usy >> 32;
380  uint64_t res;
381  if (ux)
382  {
383  if (uy)
384  goto overflow;
385  else
386  {
387  uint64_t ly = static_cast<uint32_t> (usy);
388  uint64_t uxly = ux*ly;
389  if (uxly >> 32)
390  goto overflow;
391  uxly <<= 32; // never overflows
392  uint64_t lx = static_cast<uint32_t> (usx);
393  uint64_t lxly = lx*ly;
394  res = uxly + lxly;
395  if (res < uxly)
396  goto overflow;
397  }
398  }
399  else if (uy)
400  {
401  uint64_t lx = static_cast<uint32_t> (usx);
402  uint64_t uylx = uy*lx;
403  if (uylx >> 32)
404  goto overflow;
405  uylx <<= 32; // never overflows
406  uint64_t ly = static_cast<uint32_t> (usy);
407  uint64_t lylx = ly*lx;
408  res = uylx + lylx;
409  if (res < uylx)
410  goto overflow;
411  }
412  else
413  {
414  uint64_t lx = static_cast<uint32_t> (usx);
415  uint64_t ly = static_cast<uint32_t> (usy);
416  res = lx*ly;
417  }
418 
419  if (positive)
420  {
421  if (res > static_cast<uint64_t> (max_val ()))
422  return max_val ();
423  else
424  return static_cast<int64_t> (res);
425  }
426  else
427  {
428  if (res > static_cast<uint64_t> (min_val ()))
429  return min_val ();
430  else
431  return -static_cast<int64_t> (res);
432  }
433 
434 overflow:
435  return positive ? max_val () : min_val ();
436 
437 }
438 
439 #define INT_DOUBLE_BINOP_DECL(OP,SUFFIX) \
440  template <> \
441  OCTAVE_API octave_ ## SUFFIX \
442  operator OP (const octave_ ## SUFFIX & x, const double& y)
443 
444 #define DOUBLE_INT_BINOP_DECL(OP,SUFFIX) \
445  template <> \
446  OCTAVE_API octave_ ## SUFFIX \
447  operator OP (const double& x, const octave_ ## SUFFIX & y)
448 
450 {
451  return (y < 0) ? x - octave_uint64 (-y) : x + octave_uint64 (y);
452 }
453 
455 { return y + x; }
456 
458 {
459  if (fabs (y) < static_cast<double> (octave_int64::max ()))
460  return x + octave_int64 (y);
461  else
462  {
463  // If the number is within the int64 range (the most common case,
464  // probably), the above will work as expected. If not, it's more
465  // complicated - as long as y is within _twice_ the signed range, the
466  // result may still be an integer. An instance of such an operation is
467  // 3*2**62 + (1+intmin ('int64')) that should yield int64 (2**62) + 1.
468  // So what we do is to try to convert y/2 and add it twice. Note that
469  // if y/2 overflows, the result must overflow as well, and that y/2
470  // cannot be a fractional number.
471  octave_int64 y2 (y / 2);
472  return (x + y2) + y2;
473  }
474 }
475 
477 {
478  return y + x;
479 }
480 
482 {
483  return x + (-y);
484 }
485 
487 {
488  if (x <= static_cast<double> (octave_uint64::max ()))
489  return octave_uint64 (x) - y;
490  else
491  {
492  // Again a trick to get the corner cases right. Things like
493  // 3**2**63 - intmax ('uint64') should produce the correct result, i.e.
494  // int64 (2**63) + 1.
495  const double p2_64 = std::pow (2.0, 64);
496  if (y.bool_value ())
497  {
498  const uint64_t p2_64my = (~y.value ()) + 1; // Equals 2**64 - y
499  return octave_uint64 (x - p2_64) + octave_uint64 (p2_64my);
500  }
501  else
502  return octave_uint64 (p2_64);
503  }
504 }
505 
507 {
508  return x + (-y);
509 }
510 
512 {
513  static const bool twosc = (std::numeric_limits<int64_t>::min ()
515  // In case of symmetric integers (not two's complement), this will probably
516  // be eliminated at compile time.
517  if (twosc && y.value () == std::numeric_limits<int64_t>::min ())
518  {
519  return octave_int64 (x + std::pow (2.0, 63));
520  }
521  else
522  return x + (-y);
523 }
524 
525 // NOTE:
526 // Emulated mixed multiplications are tricky due to possible precision loss.
527 // Here, after sorting out common cases for speed, we follow the strategy
528 // of converting the double number into the form sign * 64-bit integer *
529 // 2**exponent, multiply the 64-bit integers to get a 128-bit number, split that
530 // number into 32-bit words and form 4 double-valued summands (none of which
531 // loses precision), then convert these into integers and sum them. Though it
532 // is not immediately obvious, this should work even w.r.t. rounding (none of
533 // the summands lose precision).
534 
535 // Multiplies two unsigned 64-bit ints to get a 128-bit number represented
536 // as four 32-bit words.
537 static void
538 umul128 (uint64_t x, uint64_t y, uint32_t w[4])
539 {
540  uint64_t lx = static_cast<uint32_t> (x);
541  uint64_t ux = x >> 32;
542  uint64_t ly = static_cast<uint32_t> (y);
543  uint64_t uy = y >> 32;
544  uint64_t a = lx * ly;
545  w[0] = a; a >>= 32;
546  uint64_t uxly = ux*ly;
547  uint64_t uylx = uy*lx;
548  a += static_cast<uint32_t> (uxly); uxly >>= 32;
549  a += static_cast<uint32_t> (uylx); uylx >>= 32;
550  w[1] = a; a >>= 32;
551  uint64_t uxuy = ux * uy;
552  a += uxly; a += uylx; a += uxuy;
553  w[2] = a; a >>= 32;
554  w[3] = a;
555 }
556 
557 // Splits a double into bool sign, unsigned 64-bit mantissa and int exponent
558 static void
559 dblesplit (double x, bool& sign, uint64_t& mtis, int& exp)
560 {
561  sign = x < 0; x = fabs (x);
562  x = octave::math::frexp (x, &exp);
563  exp -= 52;
564  mtis = static_cast<uint64_t> (ldexp (x, 52));
565 }
566 
567 // Gets a double number from a
568 // 32-bit unsigned integer mantissa, exponent, and sign.
569 static double
570 dbleget (bool sign, uint32_t mtis, int exp)
571 {
572  double x = ldexp (static_cast<double> (mtis), exp);
573  return sign ? -x : x;
574 }
575 
577 {
578  if (y >= 0 && y < octave_uint64::max () && y == octave::math::round (y))
579  {
580  return x * octave_uint64 (static_cast<uint64_t> (y));
581  }
582  else if (y == 0.5)
583  {
584  return x / octave_uint64 (static_cast<uint64_t> (2));
585  }
586  else if (y < 0 || octave::math::isnan (y) || octave::math::isinf (y))
587  {
588  return octave_uint64 (x.value () * y);
589  }
590  else
591  {
592  bool sign;
593  uint64_t my;
594  int e;
595  dblesplit (y, sign, my, e);
596  uint32_t w[4];
597  umul128 (x.value (), my, w);
599  for (short i = 0; i < 4; i++)
600  {
601  res += octave_uint64 (dbleget (sign, w[i], e));
602  e += 32;
603  }
604  return res;
605  }
606 }
607 
609 { return y * x; }
610 
612 {
613  if (fabs (y) < octave_int64::max () && y == octave::math::round (y))
614  {
615  return x * octave_int64 (static_cast<int64_t> (y));
616  }
617  else if (fabs (y) == 0.5)
618  {
619  return x / octave_int64 (static_cast<uint64_t> (4*y));
620  }
621  else if (octave::math::isnan (y) || octave::math::isinf (y))
622  {
623  return octave_int64 (x.value () * y);
624  }
625  else
626  {
627  bool sign;
628  uint64_t my;
629  int e;
630  dblesplit (y, sign, my, e);
631  uint32_t w[4];
632  sign = (sign != (x.value () < 0));
633  umul128 (octave_int_abs (x.value ()), my, w);
635  for (short i = 0; i < 4; i++)
636  {
637  res += octave_int64 (dbleget (sign, w[i], e));
638  e += 32;
639  }
640  return res;
641  }
642 }
643 
645 { return y * x; }
646 
648 {
649  return octave_uint64 (x / static_cast<double> (y));
650 }
651 
653 {
654  return octave_int64 (x / static_cast<double> (y));
655 }
656 
658 {
659  if (y >= 0 && y < octave_uint64::max () && y == octave::math::round (y))
660  {
661  return x / octave_uint64 (y);
662  }
663  else
664  return x * (1.0/y);
665 }
666 
668 {
669  if (fabs (y) < octave_int64::max () && y == octave::math::round (y))
670  {
671  return x / octave_int64 (y);
672  }
673  else
674  return x * (1.0/y);
675 }
676 
677 #define INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP,T1,T2) \
678  template OCTAVE_API bool \
679  octave_int_cmp_op::emulate_mop<octave_int_cmp_op::OP> (T1 x, T2 y)
680 
681 #define INSTANTIATE_INT64_DOUBLE_CMP_OP(OP) \
682  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, int64_t); \
683  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, double, uint64_t); \
684  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, int64_t, double); \
685  INSTANTIATE_INT64_DOUBLE_CMP_OP0(OP, uint64_t, double)
686 
693 
694 #endif
695 
696 template <typename T>
699 {
701 
702  octave_int<T> zero = static_cast<T> (0);
703  octave_int<T> one = static_cast<T> (1);
704 
705  if (b == zero || a == one)
706  retval = one;
707  else if (b < zero)
708  {
709  if (a == -one)
710  retval = (b.value () % 2) ? a : one;
711  else
712  retval = zero;
713  }
714  else
715  {
716  octave_int<T> a_val = a;
717  T b_val = b; // no need to do saturation on b
718 
719  retval = a;
720 
721  b_val -= 1;
722 
723  while (b_val != 0)
724  {
725  if (b_val & 1)
726  retval = retval * a_val;
727 
728  b_val = b_val >> 1;
729 
730  if (b_val)
731  a_val = a_val * a_val;
732  }
733  }
734 
735  return retval;
736 }
737 
738 template <typename T>
740 pow (const double& a, const octave_int<T>& b)
741 { return octave_int<T> (std::pow (a, b.double_value ())); }
742 
743 template <typename T>
745 pow (const octave_int<T>& a, const double& b)
746 {
747  return ((b >= 0 && b < std::numeric_limits<T>::digits
748  && b == octave::math::round (b))
749  ? pow (a, octave_int<T> (static_cast<T> (b)))
750  : octave_int<T> (std::pow (a.double_value (), b)));
751 }
752 
753 template <typename T>
755 pow (const float& a, const octave_int<T>& b)
756 { return octave_int<T> (std::pow (a, b.float_value ())); }
757 
758 template <typename T>
760 pow (const octave_int<T>& a, const float& b)
761 {
762  return ((b >= 0 && b < std::numeric_limits<T>::digits
763  && b == octave::math::round (b))
764  ? pow (a, octave_int<T> (static_cast<T> (b)))
765  : octave_int<T> (std::pow (a.double_value (),
766  static_cast<double> (b))));
767 }
768 
769 // FIXME: Do we really need a differently named single-precision function
770 // integer power function here instead of an overloaded one?
771 template <typename T>
773 powf (const float& a, const octave_int<T>& b)
774 { return octave_int<T> (pow (a, b.float_value ())); }
775 
776 template <typename T>
778 powf (const octave_int<T>& a, const float& b)
779 {
780  return ((b >= 0 && b < std::numeric_limits<T>::digits
781  && b == octave::math::round (b))
782  ? pow (a, octave_int<T> (static_cast<T> (b)))
783  : octave_int<T> (std::pow (a.double_value (),
784  static_cast<double> (b))));
785 }
786 
787 #define INSTANTIATE_INTTYPE(T) \
788  template class OCTAVE_API octave_int<T>; \
789  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \
790  template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \
791  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \
792  template OCTAVE_API octave_int<T> pow (const float&, const octave_int<T>&); \
793  template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const float&); \
794  template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \
795  template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \
796  template OCTAVE_API octave_int<T> \
797  bitshift (const octave_int<T>&, int, const octave_int<T>&);
798 
803 
808 
809 /*
810 
811 %!assert (intmax ("int64") / intmin ("int64"), int64 (-1))
812 %!assert (intmin ("int64") / int64 (-1), intmax ("int64"))
813 %!assert (int64 (2**63), intmax ("int64"))
814 %!assert (uint64 (2**64), intmax ("uint64"))
815 %!test
816 %! a = 1.9*2^61; b = uint64 (a); b++; assert (b > a);
817 %!test
818 %! a = -1.9*2^61; b = int64 (a); b++; assert (b > a);
819 %!test
820 %! a = int64 (-2**60) + 2; assert (1.25*a == (5*a)/4);
821 %!test
822 %! a = uint64 (2**61) + 2; assert (1.25*a == (5*a)/4);
823 %!assert (int32 (2**31+0.5), intmax ("int32"))
824 %!assert (int32 (-2**31-0.5), intmin ("int32"))
825 %!assert ((int64 (2**62)+1)**1, int64 (2**62)+1)
826 %!assert ((int64 (2**30)+1)**2, int64 (2**60+2**31) + 1)
827 
828 %!assert <54382> (uint8 (char (128)), uint8 (128))
829 %!assert <54382> (uint8 (char (255)), uint8 (255))
830 %!assert <54382> (int8 (char (128)), int8 (128))
831 %!assert <54382> (int8 (char (255)), int8 (255))
832 
833 %!assert <54382> (uint16 (char (128)), uint16 (128))
834 %!assert <54382> (uint16 (char (255)), uint16 (255))
835 %!assert <54382> (int16 (char (128)), int16 (128))
836 %!assert <54382> (int16 (char (255)), int16 (255))
837 
838 %!assert <54382> (uint32 (char (128)), uint32 (128))
839 %!assert <54382> (uint32 (char (255)), uint32 (255))
840 %!assert <54382> (int32 (char (128)), int32 (128))
841 %!assert <54382> (int32 (char (255)), int32 (255))
842 
843 %!assert <54382> (uint64 (char (128)), uint64 (128))
844 %!assert <54382> (uint64 (char (255)), uint64 (255))
845 %!assert <54382> (int64 (char (128)), int64 (128))
846 %!assert <54382> (int64 (char (255)), int64 (255))
847 */
octave_int< uint64_t > octave_uint64
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by zero($0/0$)
#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(bool)
Definition: lo-mappers.h:187
#define DOUBLE_INT_BINOP_DECL(OP, SUFFIX)
#define INT_DOUBLE_BINOP_DECL(OP, SUFFIX)
bool isinf(double x)
Definition: lo-mappers.h:225
static const octave_int one
Definition: oct-inttypes.h:840
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
double frexp(double x, int *expptr)
Definition: lo-mappers.cc:126
i e
Definition: data.cc:2591
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:400
#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
std::complex< double > w(std::complex< double > z, double relerr=0)
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
static octave_int< T > max(void)
Definition: oct-inttypes.h:831
octave_value retval
Definition: data.cc:6246
static OCTAVE_API bool emulate_mop(double, int64_t)
#define DEFINE_REVERTED_OPERATOR(OP1, OP2)
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
static const octave_int zero
Definition: oct-inttypes.h:840
octave_int< int64_t > octave_int64
the element is set to zero In other the statement xample y
Definition: data.cc:5264
static double dbleget(bool sign, uint32_t mtis, int exp)
b
Definition: cellfun.cc:400
#define INSTANTIATE_INTTYPE(T)
static void dblesplit(double x, bool &sign, uint64_t &mtis, int &exp)
double round(double x)
Definition: lo-mappers.h:145
for i
Definition: data.cc:5264
static T convert_real(const S &value)
Definition: oct-inttypes.cc:56
nd group nd example For each display the value
Definition: sysdep.cc:866
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 const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:204