Mercurial > hg > octave-lyh
diff liboctave/oct-inttypes.h @ 4953:7a3a480e8645
[project @ 2004-09-01 21:10:28 by jwe]
author | jwe |
---|---|
date | Wed, 01 Sep 2004 21:10:28 +0000 |
parents | bfd57b466752 |
children | 573d23f9c9cf |
line wrap: on
line diff
--- a/liboctave/oct-inttypes.h +++ b/liboctave/oct-inttypes.h @@ -28,6 +28,7 @@ #include <iostream> #include "data-conv.h" +#include "lo-ieee.h" typedef signed char octave_int8_t; typedef TWO_BYTE_INT octave_int16_t; @@ -246,7 +247,13 @@ octave_int<T> operator - (void) const { - return std::numeric_limits<T>::is_signed ? -ival : 0; + // Can't just return -ival because signed types are not + // symmetric, which causes things like -intmin("int32") to be the + // same as intmin("int32") instead of intmax("int32") (which is + // what we should get with saturation semantics). + + return std::numeric_limits<T>::is_signed ? + OCTAVE_INT_FIT_TO_RANGE (- static_cast<double> (ival), T) : 0; } operator double (void) const { return static_cast<double> (value ()); } @@ -279,7 +286,8 @@ { double t = static_cast<double> (value ()); double tx = static_cast<double> (x.value ()); - ival = OCTAVE_INT_FIT_TO_RANGE (t / tx, T); + double r = (t == 0 && tx == 0) ? 0 : round (t / tx); + ival = OCTAVE_INT_FIT_TO_RANGE (r, T); return *this; } @@ -310,13 +318,13 @@ }; template <class T> -T -pow (const T& a, const T& b) +octave_int<T> +pow (const octave_int<T>& a, const octave_int<T>& b) { - T retval; + octave_int<T> retval; - T zero = T (0); - T one = T (1); + octave_int<T> zero = octave_int<T> (0); + octave_int<T> one = octave_int<T> (1); if (b == zero) retval = one; @@ -324,8 +332,8 @@ retval = zero; else { - T a_val = a; - T b_val = b; + octave_int<T> a_val = a; + octave_int<T> b_val = b; retval = a; @@ -347,6 +355,26 @@ } template <class T> +octave_int<T> +pow (double a, const octave_int<T>& b) +{ + double tb = static_cast<double> (b.value ()); + double r = pow (a, tb); + r = lo_ieee_isnan (r) ? 0 : round (r); + return OCTAVE_INT_FIT_TO_RANGE (r, T); +} + +template <class T> +octave_int<T> +pow (const octave_int<T>& a, double b) +{ + double ta = static_cast<double> (a.value ()); + double r = pow (ta, b); + r = lo_ieee_isnan (r) ? 0 : round (r); + return OCTAVE_INT_FIT_TO_RANGE (r, T); +} + +template <class T> std::ostream& operator << (std::ostream& os, const octave_int<T>& ival) { @@ -389,7 +417,50 @@ OCTAVE_INT_BIN_OP(+) OCTAVE_INT_BIN_OP(-) OCTAVE_INT_BIN_OP(*) -OCTAVE_INT_BIN_OP(/) + +template <class T1, class T2> +octave_int<typename octave_int_binop_traits<T1, T2>::TR> +operator / (const octave_int<T1>& x, const octave_int<T2>& y) +{ + double tx = static_cast<double> (x.value ()); + double ty = static_cast<double> (y.value ()); + double r = (tx == 0 && ty == 0) ? 0 : tx / ty; + return OCTAVE_INT_FIT_TO_RANGE2 (r, T1, T2); +} + +#define OCTAVE_INT_DOUBLE_BIN_OP(OP) \ + \ + template <class T> \ + octave_int<T> \ + operator OP (const octave_int<T>& x, double y) \ + { \ + double tx = static_cast<double> (x.value ()); \ + double r = round (tx OP y); \ + r = lo_ieee_isnan (r) ? 0 : round (r); \ + return OCTAVE_INT_FIT_TO_RANGE (r, T); \ + } + +OCTAVE_INT_DOUBLE_BIN_OP(+) +OCTAVE_INT_DOUBLE_BIN_OP(-) +OCTAVE_INT_DOUBLE_BIN_OP(*) +OCTAVE_INT_DOUBLE_BIN_OP(/) + +#define OCTAVE_DOUBLE_INT_BIN_OP(OP) \ + \ + template <class T> \ + octave_int<T> \ + operator OP (double x, const octave_int<T>& y) \ + { \ + double ty = static_cast<double> (y.value ()); \ + double r = x OP ty; \ + r = lo_ieee_isnan (r) ? 0 : round (r); \ + return OCTAVE_INT_FIT_TO_RANGE (r, T); \ + } + +OCTAVE_DOUBLE_INT_BIN_OP(+) +OCTAVE_DOUBLE_INT_BIN_OP(-) +OCTAVE_DOUBLE_INT_BIN_OP(*) +OCTAVE_DOUBLE_INT_BIN_OP(/) #define OCTAVE_INT_BITCMP_OP(OP) \ \