octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Add additional integer math and conversion warnings and the intwarni


From: David Bateman
Subject: Re: Add additional integer math and conversion warnings and the intwarning function
Date: Tue, 19 Aug 2008 11:27:05 +0200
User-agent: Thunderbird 2.0.0.16 (X11/20080725)

David Bateman wrote:
Attached is a patch that adds the warnings

Octave:int-convert-nan
Octave:int-convert-non-int-val
Octave:int-math-overflow

and the intwarning function to control them. Initially they are off by default. For example consider

octave:1> intwarning("query")
The state of warning "Octave:int-convert-nan" is "off"
The state of warning "Octave:int-convert-non-int-val" is "off"
The state of warning "Octave:int-convert-overflow" is "off"
The state of warning "Octave:int-math-overflow" is "off"

octave:2> a = uint8(254.7)
a = 255
octave:3> a + 1
ans = 255
octave:4> intwarning("on")
octave:5> a = uint8(254.7)
warning: Conversion of non-integer value from scalar to uint8 matrix
a = 255
octave:6> a + 1
warning: data truncated converting from uint8 scalar to scalar
ans = 255

regards
David

Please use the attached version instead as it improves the error messages. For example

octave:1> intwarning("on")
octave:2> a = uint8(254.7)
warning: Conversion of non-integer value from scalar to uint8 matrix
a = 255
octave:3> a + 1
warning: data truncated for uint8 scalar by scalar binary operator +
ans = 255

Regards
David


--
David Bateman                                address@hidden
Motorola Labs - Paris +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 6 72 01 06 33 (Mob) 91193 Gif-Sur-Yvette FRANCE +33 1 69 35 77 01 (Fax) The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary

# HG changeset patch
# User David Bateman <address@hidden>
# Date 1219137748 -7200
# Node ID 02bdc652e429d6c667a7b58909c7cc1014154821
# Parent  c4299e79f1d01a008b4cecb492b8934d756ccb89
Add additional integer math and conversion warnings, set their default state to 
be off and add the intwarning function

diff --git a/doc/ChangeLog b/doc/ChangeLog
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,7 @@ 2008-08-06  Søren Hauberg  <address@hidden
+2008-08-19  David Bateman  <address@hidden>
+
+       * interpreter/numbers.txi: Document intwarning.
+
 2008-08-06  Søren Hauberg  <address@hidden>
 
        * interpreter/basics.txi, interpreter/errors.txi,
diff --git a/doc/interpreter/numbers.txi b/doc/interpreter/numbers.txi
--- a/doc/interpreter/numbers.txi
+++ b/doc/interpreter/numbers.txi
@@ -492,6 +492,8 @@ when converted.
 
 @DOCSTRING(intmin)
 
address@hidden(intwarning)
+
 @menu
 * Integer Arithmetic::
 @end menu
diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog
--- a/liboctave/ChangeLog
+++ b/liboctave/ChangeLog
@@ -1,3 +1,35 @@ 2008-08-12  Jaroslav Hajek <address@hidden
+2008-08-19  David Bateman  <address@hidden>
+
+       * oct-inttypes.h (template <class T1, class T2> inline T2
+       octave_int_fit_to_range (const T1&, const T2&, const T2&),
+       template <typename T> inline T octave_int_fit_to_range (const
+       double&, const T&, const T&), template <> inline T2
+       octave_int_fit_to_range<T1, T2> (const T1&, const T2&, const T2&),
+       OCTAVE_S_US_FTR): Check and flag integer trunctation.
+       (OCTAVE_INT_FIT_TO_RANGE, OCTAVE_INT_FIT_TO_RANGE2): Adapt for the
+       above change.
+       (OCTAVE_INT_CONV_FIT_TO_RANGE): New macro for conversion to
+       integer types.
+       (octave_int<T>::conv_error_type): New enum to flag conversion and
+       math warnings.
+       (octave_int<T>::octave_int (U i), octave_int<T>::octave_int
+       (double i), octave_int<>::octave_int (const octave_int<U>& i)):
+       Flag conversion and math errors other than integer truncation.
+       (octave_int<T> octave_int<T>::operator - (void)): Flag truncation
+       error.
+       (static bool get_trunc_flag (void), static bool clear_trunc_flag
+       (void, static bool trunc_flag)): Delete.
+       (static int get_conv_flag (void), static bool get_trunc_flag (void),
+       static bool get_nan_flag (void), static bool get_non_int_flag (void),
+       static bool get_math_trunc_flag (void), static void
+       clear_conv_flag (void)): New functions to query and reset
+       conversion and mathw arning state.
+       (static int cov_flag): New parameter holding current conversion
+       and math warning state. Set it to zero.
+       (template <class T> octave_int<T> powf (float, const
+       octave_int<T>&), template <class T> octave_int<T> powf (const
+       octave_int<T>&, float)): New functions.
+       
 2008-08-12  Jaroslav Hajek <address@hidden>
 
        * lo-ieee.cc (octave_ieee_init): Try to ensure that octave_NaN is
diff --git a/liboctave/oct-inttypes.h b/liboctave/oct-inttypes.h
--- a/liboctave/oct-inttypes.h
+++ b/liboctave/oct-inttypes.h
@@ -124,16 +124,26 @@ OCTAVE_INT_BINOP_TRAIT (uint64_t, uint64
 
 template <class T1, class T2>
 inline T2
-octave_int_fit_to_range (const T1& x, const T2& mn, const T2& mx)
-{
-  return (x > mx ? mx : (x < mn ? mn : T2 (x)));
+octave_int_fit_to_range (const T1& x, const T2& mn, const T2& mx,
+                        int& conv_flag, int math_truncate)
+{
+  bool out_of_range_max = x > mx;
+  bool out_of_range_min = x < mn;
+  conv_flag |= (out_of_range_max || out_of_range_min ? math_truncate : 0);
+  return (out_of_range_max ? mx : (out_of_range_min ? mn : T2 (x)));
 }
 
 template <typename T>
 inline T
-octave_int_fit_to_range (const double& x, const T& mn, const T& mx)
-{
-  return (__lo_ieee_isnan (x) ? 0 : (x > mx ? mx : (x < mn ? mn : 
static_cast<T> (x))));
+octave_int_fit_to_range (const double& x, const T& mn, const T& mx,
+                        int& conv_flag, int math_truncate)
+{
+  bool out_of_range_max = x > mx;
+  bool out_of_range_min = x < mn;
+  conv_flag |= (out_of_range_max || out_of_range_min ? math_truncate : 0);
+  return (__lo_ieee_isnan (x)
+         ? 0 : (out_of_range_max
+                ? mx : (out_of_range_min ? mn : static_cast<T> (x))));
 }
 
 // If X is unsigned and the new type is signed, then we only have to
@@ -145,9 +155,12 @@ octave_int_fit_to_range (const double& x
 #define OCTAVE_US_S_FTR(T1, T2, TC) \
   template <> \
   inline T2 \
-  octave_int_fit_to_range<T1, T2> (const T1& x, const T2&, const T2& mx) \
-  { \
-    return x > static_cast<TC> (mx) ? mx : x; \
+  octave_int_fit_to_range<T1, T2> (const T1& x, const T2&, const T2& mx, \
+                                  int& conv_flag, int math_truncate) \
+  { \
+    bool out_of_range = x > static_cast<TC> (mx); \
+    conv_flag |= (out_of_range ? math_truncate : 0); \
+    return out_of_range ? mx : x; \
   }
 
 #define OCTAVE_US_S_FTR_FCNS(T) \
@@ -172,10 +185,13 @@ OCTAVE_US_S_FTR_FCNS (unsigned long long
 #define OCTAVE_S_US_FTR(T1, T2) \
   template <> \
   inline T2 \
-  octave_int_fit_to_range<T1, T2> (const T1& x, const T2&, const T2&) \
-  { \
+  octave_int_fit_to_range<T1, T2> (const T1& x, const T2&, const T2&, \
+                                  int& conv_flag, int math_truncate) \
+  { \
+    bool out_of_range = x < 0; \
+    conv_flag |= (out_of_range ? math_truncate : 0); \
     return x <= 0 ? 0 : x; \
-  }
+   }
 
 #define OCTAVE_S_US_FTR_FCNS(T) \
   OCTAVE_S_US_FTR (T, unsigned char) \
@@ -191,10 +207,19 @@ OCTAVE_S_US_FTR_FCNS (long)
 OCTAVE_S_US_FTR_FCNS (long)
 OCTAVE_S_US_FTR_FCNS (long long)
 
+#define OCTAVE_INT_CONV_FIT_TO_RANGE(r, T) \
+  octave_int_fit_to_range (r, \
+                           std::numeric_limits<T>::min (), \
+                           std::numeric_limits<T>::max (), \
+                          octave_int<T>::conv_flag, \
+                          octave_int<T>::int_truncate)
+
 #define OCTAVE_INT_FIT_TO_RANGE(r, T) \
   octave_int_fit_to_range (r, \
                            std::numeric_limits<T>::min (), \
-                           std::numeric_limits<T>::max ())
+                           std::numeric_limits<T>::max (), \
+                          octave_int<T>::conv_flag, \
+                          octave_int<T>::math_truncate)
 
 #define OCTAVE_INT_MIN_VAL2(T1, T2) \
   std::numeric_limits<typename octave_int_binop_traits<T1, T2>::TR>::min ()
@@ -205,7 +230,9 @@ OCTAVE_S_US_FTR_FCNS (long long)
 #define OCTAVE_INT_FIT_TO_RANGE2(r, T1, T2) \
   octave_int_fit_to_range (r, \
                            OCTAVE_INT_MIN_VAL2 (T1, T2), \
-                           OCTAVE_INT_MAX_VAL2 (T1, T2))
+                           OCTAVE_INT_MAX_VAL2 (T1, T2), \
+                          octave_int<typename octave_int_binop_traits<T1, 
T2>::TR>::conv_flag, \
+                          octave_int<typename octave_int_binop_traits<T1, 
T2>::TR>::math_truncate)
 
 // We have all the machinery below (octave_int_helper) to avoid a few
 // warnings from GCC about comparisons always false due to limited
@@ -268,24 +295,34 @@ octave_int
 octave_int
 {
 public:
+  enum conv_error_type
+    {
+      int_truncate = 1,
+      conv_nan = 2,
+      conv_non_int = 4,
+      math_truncate = 8
+    };
 
   typedef T val_type;
 
   octave_int (void) : ival () { }
 
   template <class U>
-  octave_int (U i) : ival (OCTAVE_INT_FIT_TO_RANGE (i, T)) { }
-
-  octave_int (double d) : ival (OCTAVE_INT_FIT_TO_RANGE (xround (d), T)) { }
+  octave_int (U i) : ival (OCTAVE_INT_CONV_FIT_TO_RANGE (i, T)) { }
+
+  octave_int (double d) : ival (OCTAVE_INT_CONV_FIT_TO_RANGE (xround (d), T)) 
+    { 
+      if (xisnan (d))
+       conv_flag |= conv_nan;
+      else
+       conv_flag |= (d != xround (d) ? conv_non_int : 0);
+    }
 
   octave_int (bool b) : ival (b) { }
 
   template <class U>
   octave_int (const octave_int<U>& i)
-    : ival (OCTAVE_INT_FIT_TO_RANGE (i.value (), T)) 
-    { 
-      trunc_flag = trunc_flag || (ival != i.value ());
-    }
+    : ival (OCTAVE_INT_CONV_FIT_TO_RANGE (i.value (), T)) { }
 
   octave_int (const octave_int<T>& i) : ival (i.ival) { }
 
@@ -312,9 +349,13 @@ public:
     // 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;
+    if (std::numeric_limits<T>::is_signed)
+      return OCTAVE_INT_FIT_TO_RANGE (- static_cast<double> (ival), T);
+    else
+      {
+       conv_flag |= math_truncate;
+       return 0;
+      }
   }
 
   bool bool_value (void) const { return static_cast<bool> (value ()); }
@@ -402,8 +443,12 @@ public:
 
   static int byte_size (void) { return sizeof(T); }
 
-  static bool get_trunc_flag () { return trunc_flag; }
-  static void clear_trunc_flag () { trunc_flag = false; }
+  static int get_conv_flag () { return conv_flag; }
+  static bool get_trunc_flag () { return (conv_flag & int_truncate); }
+  static bool get_nan_flag () { return (conv_flag & conv_nan); }
+  static bool get_non_int_flag () { return (conv_flag & conv_non_int); }
+  static bool get_math_trunc_flag () { return (conv_flag & math_truncate); }
+  static void clear_conv_flag () { conv_flag = 0; }
 
   static const char *type_name () { return "unknown type"; }
 
@@ -411,13 +456,14 @@ public:
   // You should not use it anywhere else.
   void *mex_get_data (void) const { return const_cast<T *> (&ival); }
 
+  static int conv_flag;
+
 private:
 
-  static bool trunc_flag;
   T ival;
 };
 
-template<class T> bool octave_int<T>::trunc_flag = false; 
+template<class T> int octave_int<T>::conv_flag = 0;
 
 template <class T>
 bool
@@ -480,6 +526,26 @@ 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 : xround (r);
+  return OCTAVE_INT_FIT_TO_RANGE (r, T);
+}
+
+template <class T>
+octave_int<T>
+powf (float a, const octave_int<T>& b)
+{
+  float tb = static_cast<float> (b.value ());
+  float r = powf (a, tb);
+  r = __lo_ieee_float_isnan (r) ? 0 : xround (r);
+  return OCTAVE_INT_FIT_TO_RANGE (r, T);
+}
+
+template <class T>
+octave_int<T>
+powf (const octave_int<T>& a, float b)
+{
+  float ta = static_cast<float> (a.value ());
+  float r = pow (ta, b);
+  r = __lo_ieee_float_isnan (r) ? 0 : xround (r);
   return OCTAVE_INT_FIT_TO_RANGE (r, T);
 }
 
diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,4 +1,7 @@ 2008-08-18  David Bateman  <address@hidden
-2008-08-18  David Bateman  <address@hidden>
+2008-08-19  David Bateman  <address@hidden>
+
+       * miscellaneous/intwarning.m: New function.
+       * miscellaneous/Makefile.in (SOURCES): Add it here.
        
        * statistics/base/ranks.m: Doc fix.
 
diff --git a/scripts/miscellaneous/Makefile.in 
b/scripts/miscellaneous/Makefile.in
--- a/scripts/miscellaneous/Makefile.in
+++ b/scripts/miscellaneous/Makefile.in
@@ -37,11 +37,11 @@ SOURCES = ans.m bincoeff.m bug_report.m 
   compare_versions.m computer.m copyfile.m debug.m \
   delete.m dir.m doc.m dos.m dump_prefs.m edit.m \
   fileattrib.m fileparts.m flops.m fullfile.m getfield.m gunzip.m gzip.m \
-  info.m inputname.m ismac.m ispc.m isunix.m license.m list_primes.m ls.m \
-  ls_command.m menu.m mex.m mexext.m mkoctfile.m movefile.m \
-  namelengthmax.m news.m orderfields.m pack.m paren.m parseparams.m perl.m\
-  run.m semicolon.m setfield.m substruct.m swapbytes.m symvar.m \
-  tar.m tempdir.m tempname.m texas_lotto.m unix.m unpack.m untar.m \
+  info.m inputname.m intwarning.m ismac.m ispc.m isunix.m license.m \
+  list_primes.m ls.m ls_command.m menu.m mex.m mexext.m mkoctfile.m \
+  movefile.m namelengthmax.m news.m orderfields.m pack.m paren.m \
+  parseparams.m perl.m run.m semicolon.m setfield.m substruct.m swapbytes.m \
+  symvar.m tar.m tempdir.m tempname.m texas_lotto.m unix.m unpack.m untar.m \
   unzip.m ver.m version.m warning_ids.m what.m xor.m zip.m
 
 DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
diff --git a/scripts/miscellaneous/intwarning.m 
b/scripts/miscellaneous/intwarning.m
new file mode 100644
--- /dev/null
+++ b/scripts/miscellaneous/intwarning.m
@@ -0,0 +1,125 @@
+## Copyright (C) 2008  David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} intwarning (@var{action})
+## @deftypefnx {Function File} {} intwarning (@var{s})
+## @deftypefnx {Function File} address@hidden =} intwarning (@dots{})
+## Control the state of the warning for integer conversions and math
+## operations.
+##
+## @table @asis
+## @item "query"
+## The state of the Octave integer conversion and math warnings is
+## queried. If there is no output argument, then the state is printed.
+## Otherwise it is returned in a structure with the fields "identifier"
+## and "state".
+##
+## @example
+## intwarning ("query")
+## The state of warning "Octave:int-convert-nan" is "off"
+## The state of warning "Octave:int-convert-non-int-val" is "off"
+## The state of warning "Octave:int-convert-overflow" is "off"
+## The state of warning "Octave:int-math-overflow" is "off"
+## @end example 
+##
+## @item "on"
+## Turn integer conversion and math warnings "on". If there is no output
+## argument, then nothing is printed. Otherwise the original state of
+## the state of the integer conversion and math warnings is returned in
+## a structure array.
+##
+## @item "off"
+## Turn integer conversion and math warnings "on". If there is no output
+## argument, then nothing is printed. Otherwise the original state of
+## the state of the integer conversion and math warnings is returned in
+## a structure array.
+## @end table
+##
+## The original state of the integer warnings can be restored by passing
+## the structure array returned by @code{intwarning} to a later call to
+## @code{intwarning}. For example
+##
+## @example
+## s = intwarning ("off");
+## @dots{}
+## intwarning (s);
+## @end example
+## @seealso{warning}
+## @end deftypefn
+
+## PKG_ADD: mark_as_command intwarning
+
+function y = intwarning (x)
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    if (nargout > 0)
+      y = warning("query", "Octave:int-convert-nan");
+      y = [y; warning("query", "Octave:int-convert-non-int-val")];
+      y = [y; warning("query", "Octave:int-convert-overflow")];
+      y = [y; warning("query", "Octave:int-math-overflow")];
+    endif
+    if (ischar (x))
+      if (strcmpi (x, "query"))
+       if (nargout == 0)
+         __print_int_warn_state__ ("Octave:int-convert-nan");
+         __print_int_warn_state__ ("Octave:int-convert-non-int-val");
+         __print_int_warn_state__ ("Octave:int-convert-overflow");
+         __print_int_warn_state__ ("Octave:int-math-overflow");
+         printf("\n");
+       endif
+      elseif (strcmpi (x, "on"))
+       warning ("on", "Octave:int-convert-nan");
+       warning ("on", "Octave:int-convert-non-int-val");
+       warning ("on", "Octave:int-convert-overflow");
+       warning ("on", "Octave:int-math-overflow");
+      elseif (strcmpi (x, "off"))
+       warning ("off", "Octave:int-convert-nan");
+       warning ("off", "Octave:int-convert-non-int-val");
+       warning ("off", "Octave:int-convert-overflow");    
+       warning ("off", "Octave:int-math-overflow");    
+      else
+       error ("intwarning: unrecognized argument");
+      endif
+    elseif (isstruct(x))
+      for fld = fieldnames (x)
+       if (strcmp ("Octave:int-convert-nan") || 
+           strcmp ("Octave:int-convert-non-int-val") || 
+           strcmp ("Octave:int-convert-overflow") ||
+           strcmp ("Octave:int-cmath-overflow"))
+         s = getfield (x, fld);
+         if (! ischar (s) || !(strcmpi("s","on") || strcmpi("s","off")))
+           error ("intwarning: unexpected warning state");
+         endif
+         warning (s, fld);
+       else
+         error ("intwarning: unrecognized integer warning %s", fld);
+       endif
+      endfor
+    else
+      error ("intwarning: unexpected input");
+    endif
+  endif
+endfunction
+
+function __print_int_warn_state__ (s)
+  fprintf ("The state of warning \"%s\" is \"%s\"\n", 
+          s, warning ("query", s).state);
+endfunction
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,36 @@ 2008-08-12  John W. Eaton  <address@hidden
+2008-08-19  David Bateman  <address@hidden>
+
+       * OPERATORS/op-int-conv.cc (DEFINTCONVFN): New macro that warn
+       for integer conversion issues. Use it to replace DEFCONVFN.
+       * OPERATORS/op-int.h (DEFINTBINOP_OP, DEFINTNDBINOP_OP,
+       DEFINTBINOP_FN, DEFINTNDBINOP_FN): New macros that warn for
+       integer truncation issues. Use them to replace the corresponding
+       macros in the integer arithmetic macros. Update other integer
+       arithmetic functions that don't use these macros individually.
+       * error.cc (initialize_default_warning_state (void)): Initialize
+       the default warning state for the integer warnings to be off.
+       * gripes.cc (void gripe_binop_integer_math_truncated (const char *,
+       const char *, const char *), void gripe_unop_integer_math_truncated
+       (const char *, const char *), void gripe_non_integer_conversion
+       (const char *, const char *), void gripe_nan_conversion (const char *,
+       const char *)): Warning functions for integer conversion and math
+       issues.
+       * gripes.h (void gripe_binop_integer_math_truncated (const char *,
+       const char *, const char *), void gripe_unop_integer_math_truncated
+       (const char *, const char *), void gripe_non_integer_conversion
+       (const char *, const char *), void gripe_nan_conversion (const char *,
+       const char *)): Declare them.
+       * ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::convert_gripe,
+       OCTAVE_VALUE_INT_SCALAR_T::convert_gripe): Adapt for new means of
+       flagging integer truncation.
+       (OCTAVE_VALUE_INT_MATRIX_T::decrement,
+       OCTAVE_VALUE_INT_MATRIX_T::increment,
+       OCTAVE_VALUE_INT_SCALAR_T::decrement,
+       OCTAVE_VALUE_INT_SCALAR_T::increment): Check for integer
+       truncation.
+       * ov.cc (convert_to_int_array): Adapt for new means of
+       flagging integer truncation.
+
 2008-08-12  John W. Eaton  <address@hidden>
 
        * pt-fcn-handle.cc (tree_anon_fcn_handle::rvalue):
diff --git a/src/OPERATORS/op-int-conv.cc b/src/OPERATORS/op-int-conv.cc
--- a/src/OPERATORS/op-int-conv.cc
+++ b/src/OPERATORS/op-int-conv.cc
@@ -46,47 +46,67 @@ along with Octave; see the file COPYING.
 #include "ov-typeinfo.h"
 #include "ops.h"
 
+#define DEFINTCONVFN(name, tfrom, tto) \
+  CONVDECL (name) \
+  { \
+    CAST_CONV_ARG (const octave_ ## tfrom&); \
+ \
+    octave_ ## tto ::clear_conv_flag (); \
+    octave_ ## tto ## _matrix v2 = v.tto ## _array_value (); \
+    if (octave_ ## tto ::get_trunc_flag ()) \
+      gripe_truncated_conversion (v.type_name (). c_str (), \
+                                 v2.type_name (). c_str ()); \
+    if (octave_ ## tto ::get_nan_flag ()) \
+      gripe_nan_conversion (v.type_name (). c_str (), \
+                           v2.type_name (). c_str ()); \
+    if (octave_ ## tto ::get_non_int_flag ()) \
+      gripe_non_integer_conversion (v.type_name (). c_str (), \
+                                   v2.type_name (). c_str ()); \
+    octave_ ## tto ::clear_conv_flag (); \
+    return new octave_ ## tto ## _matrix (v2); \
+  }
+
 // conversion ops
 
-DEFCONVFN (scalar_to_int8, scalar, int8)
-DEFCONVFN (scalar_to_int16, scalar, int16)
-DEFCONVFN (scalar_to_int32, scalar, int32)
-DEFCONVFN (scalar_to_int64, scalar, int64)
-
-DEFCONVFN (scalar_to_uint8, scalar, uint8)
-DEFCONVFN (scalar_to_uint16, scalar, uint16)
-DEFCONVFN (scalar_to_uint32, scalar, uint32)
-DEFCONVFN (scalar_to_uint64, scalar, uint64)
-
-DEFCONVFN (matrix_to_int8, matrix, int8)
-DEFCONVFN (matrix_to_int16, matrix, int16)
-DEFCONVFN (matrix_to_int32, matrix, int32)
-DEFCONVFN (matrix_to_int64, matrix, int64)
-
-DEFCONVFN (matrix_to_uint8, matrix, uint8)
-DEFCONVFN (matrix_to_uint16, matrix, uint16)
-DEFCONVFN (matrix_to_uint32, matrix, uint32)
-DEFCONVFN (matrix_to_uint64, matrix, uint64)
-
-DEFCONVFN (float_scalar_to_int8, float_scalar, int8)
-DEFCONVFN (float_scalar_to_int16, float_scalar, int16)
-DEFCONVFN (float_scalar_to_int32, float_scalar, int32)
-DEFCONVFN (float_scalar_to_int64, float_scalar, int64)
-
-DEFCONVFN (float_scalar_to_uint8, float_scalar, uint8)
-DEFCONVFN (float_scalar_to_uint16, float_scalar, uint16)
-DEFCONVFN (float_scalar_to_uint32, float_scalar, uint32)
-DEFCONVFN (float_scalar_to_uint64, float_scalar, uint64)
-
-DEFCONVFN (float_matrix_to_int8, float_matrix, int8)
-DEFCONVFN (float_matrix_to_int16, float_matrix, int16)
-DEFCONVFN (float_matrix_to_int32, float_matrix, int32)
-DEFCONVFN (float_matrix_to_int64, float_matrix, int64)
-
-DEFCONVFN (float_matrix_to_uint8, float_matrix, uint8)
-DEFCONVFN (float_matrix_to_uint16, float_matrix, uint16)
-DEFCONVFN (float_matrix_to_uint32, float_matrix, uint32)
-DEFCONVFN (float_matrix_to_uint64, float_matrix, uint64)
+DEFINTCONVFN (scalar_to_int8, scalar, int8)
+DEFINTCONVFN (scalar_to_int16, scalar, int16)
+DEFINTCONVFN (scalar_to_int32, scalar, int32)
+DEFINTCONVFN (scalar_to_int64, scalar, int64)
+
+DEFINTCONVFN (scalar_to_uint8, scalar, uint8)
+DEFINTCONVFN (scalar_to_uint16, scalar, uint16)
+DEFINTCONVFN (scalar_to_uint32, scalar, uint32)
+DEFINTCONVFN (scalar_to_uint64, scalar, uint64)
+
+DEFINTCONVFN (matrix_to_int8, matrix, int8)
+DEFINTCONVFN (matrix_to_int16, matrix, int16)
+DEFINTCONVFN (matrix_to_int32, matrix, int32)
+DEFINTCONVFN (matrix_to_int64, matrix, int64)
+
+DEFINTCONVFN (matrix_to_uint8, matrix, uint8)
+DEFINTCONVFN (matrix_to_uint16, matrix, uint16)
+DEFINTCONVFN (matrix_to_uint32, matrix, uint32)
+DEFINTCONVFN (matrix_to_uint64, matrix, uint64)
+
+DEFINTCONVFN (float_scalar_to_int8, float_scalar, int8)
+DEFINTCONVFN (float_scalar_to_int16, float_scalar, int16)
+DEFINTCONVFN (float_scalar_to_int32, float_scalar, int32)
+DEFINTCONVFN (float_scalar_to_int64, float_scalar, int64)
+
+DEFINTCONVFN (float_scalar_to_uint8, float_scalar, uint8)
+DEFINTCONVFN (float_scalar_to_uint16, float_scalar, uint16)
+DEFINTCONVFN (float_scalar_to_uint32, float_scalar, uint32)
+DEFINTCONVFN (float_scalar_to_uint64, float_scalar, uint64)
+
+DEFINTCONVFN (float_matrix_to_int8, float_matrix, int8)
+DEFINTCONVFN (float_matrix_to_int16, float_matrix, int16)
+DEFINTCONVFN (float_matrix_to_int32, float_matrix, int32)
+DEFINTCONVFN (float_matrix_to_int64, float_matrix, int64)
+
+DEFINTCONVFN (float_matrix_to_uint8, float_matrix, uint8)
+DEFINTCONVFN (float_matrix_to_uint16, float_matrix, uint16)
+DEFINTCONVFN (float_matrix_to_uint32, float_matrix, uint32)
+DEFINTCONVFN (float_matrix_to_uint64, float_matrix, uint64)
 
 DEFCONVFN (bool_to_int8, bool, int8)
 DEFCONVFN (bool_to_int16, bool, int16)
@@ -128,15 +148,15 @@ DEFSTRINTCONVFN (char_matrix_dq_str_to_u
 DEFSTRINTCONVFN (char_matrix_dq_str_to_uint32, uint32)
 DEFSTRINTCONVFN (char_matrix_dq_str_to_uint64, uint64)
 
-DEFCONVFN (range_to_int8, range, int8)
-DEFCONVFN (range_to_int16, range, int16)
-DEFCONVFN (range_to_int32, range, int32)
-DEFCONVFN (range_to_int64, range, int64)
-
-DEFCONVFN (range_to_uint8, range, uint8)
-DEFCONVFN (range_to_uint16, range, uint16)
-DEFCONVFN (range_to_uint32, range, uint32)
-DEFCONVFN (range_to_uint64, range, uint64)
+DEFINTCONVFN (range_to_int8, range, int8)
+DEFINTCONVFN (range_to_int16, range, int16)
+DEFINTCONVFN (range_to_int32, range, int32)
+DEFINTCONVFN (range_to_int64, range, int64)
+
+DEFINTCONVFN (range_to_uint8, range, uint8)
+DEFINTCONVFN (range_to_uint16, range, uint16)
+DEFINTCONVFN (range_to_uint32, range, uint32)
+DEFINTCONVFN (range_to_uint64, range, uint64)
 
 #define INT_CONV_FUNCTIONS(tfrom) \
   DEFCONVFN2 (tfrom ## _scalar_to_int8, tfrom, scalar, int8) \
diff --git a/src/OPERATORS/op-int.h b/src/OPERATORS/op-int.h
--- a/src/OPERATORS/op-int.h
+++ b/src/OPERATORS/op-int.h
@@ -21,6 +21,56 @@ along with Octave; see the file COPYING.
 */
 
 #include "quit.h"
+
+#define DEFINTBINOP_OP(name, t1, t2, op, t3) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value \
+      (v1.t1 ## _value () op v2.t2 ## _value ()); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define DEFINTNDBINOP_OP(name, t1, t2, e1, e2, op, t3) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value \
+      (v1.e1 ## _value () op v2.e2 ## _value ()); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define DEFINTBINOP_FN(name, t1, t2, f, t3, op)        \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value (f (v1.t1 ## _value (), v2.t2 ## _value 
())); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
+
+#define DEFINTNDBINOP_FN(name, t1, t2, e1, e2, f, t3, op)      \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    octave_value retval = octave_value (f (v1.e1 ## _value (), v2.e2 ## _value 
())); \
+    if (octave_ ## t3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (#op, v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## t3 ::clear_conv_flag (); \
+    return retval; \
+  }
 
 #define OCTAVE_CONCAT_FN2(T1, T2) \
   DEFNDCATOP_FN2 (T1 ## _ ## T2 ## _s_s, T1 ## _scalar, T2 ## _scalar, , T1 ## 
NDArray, T1 ## _array, T2 ## _array, concat) \
@@ -122,19 +172,27 @@ along with Octave; see the file COPYING.
  \
   DEFUNOP_OP (s_not, TYPE ## _scalar, !) \
   DEFUNOP_OP (s_uplus, TYPE ## _scalar, /* no-op */) \
-  DEFUNOP_OP (s_uminus, TYPE ## _scalar, -) \
+  DEFUNOP (s_uminus, TYPE ## _scalar) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## TYPE ## _scalar &); \
+    octave_value retval = octave_value (- v. TYPE ## _scalar_value ()); \
+    if (octave_ ## TYPE ::get_math_trunc_flag ()) \
+      gripe_unop_integer_math_truncated ("-", v.type_name (). c_str ()); \
+    octave_ ## TYPE ::clear_conv_flag (); \
+    return retval; \
+  } \
   DEFUNOP_OP (s_transpose, TYPE ## _scalar, /* no-op */) \
   DEFUNOP_OP (s_hermitian, TYPE ## _scalar, /* no-op */) \
  \
   DEFNCUNOP_METHOD (s_incr, TYPE ## _scalar, increment) \
   DEFNCUNOP_METHOD (s_decr, TYPE ## _scalar, decrement)
 
-#define OCTAVE_SS_INT_ARITH_OPS(PFX, T1, T2) \
+#define OCTAVE_SS_INT_ARITH_OPS(PFX, T1, T2, T3)       \
   /* scalar by scalar ops. */ \
  \
-  DEFBINOP_OP (PFX ## _add, T1 ## scalar, T2 ## scalar, +) \
-  DEFBINOP_OP (PFX ## _sub, T1 ## scalar, T2 ## scalar, -) \
-  DEFBINOP_OP (PFX ## _mul, T1 ## scalar, T2 ## scalar, *) \
+  DEFINTBINOP_OP (PFX ## _add, T1 ## scalar, T2 ## scalar, +, T3) \
+  DEFINTBINOP_OP (PFX ## _sub, T1 ## scalar, T2 ## scalar, -, T3) \
+  DEFINTBINOP_OP (PFX ## _mul, T1 ## scalar, T2 ## scalar, *, T3) \
  \
   DEFBINOP (PFX ## _div, T1 ## scalar, T2 ## scalar) \
   { \
@@ -143,10 +201,15 @@ along with Octave; see the file COPYING.
     if (! v2.T2 ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v1.T1 ## scalar_value () / v2.T2 ## scalar_value ()); 
\
-  } \
- \
-  DEFBINOP_FN (PFX ## _pow, T1 ## scalar, T2 ## scalar, xpow) \
+    octave_value retval = octave_value (v1.T1 ## scalar_value () / v2.T2 ## 
scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("/", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTBINOP_FN (PFX ## _pow, T1 ## scalar, T2 ## scalar, xpow, T3, ^)        
\
  \
   DEFBINOP (PFX ## _ldiv, T1 ## scalar, T2 ## scalar) \
   { \
@@ -155,10 +218,15 @@ along with Octave; see the file COPYING.
     if (! v1.T1 ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v2.T2 ## scalar_value () / v1.T1 ## scalar_value ()); 
\
-  } \
- \
-  DEFBINOP_OP (PFX ## _el_mul, T1 ## scalar, T2 ## scalar, *) \
+    octave_value retval = octave_value (v2.T2 ## scalar_value () / v1.T1 ## 
scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+          gripe_binop_integer_math_truncated ("\\", v1.type_name (). c_str (), 
\
+                                             v2.type_name (). c_str ()); \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTBINOP_OP (PFX ## _el_mul, T1 ## scalar, T2 ## scalar, *, T3)   \
  \
   DEFBINOP (PFX ## _el_div, T1 ## scalar, T2 ## scalar) \
   { \
@@ -167,10 +235,15 @@ along with Octave; see the file COPYING.
     if (! v2.T2 ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v1.T1 ## scalar_value () / v2.T2 ## scalar_value ()); 
\
-  } \
- \
-  DEFBINOP_FN (PFX ## _el_pow, T1 ## scalar, T2 ## scalar, xpow) \
+    octave_value retval = octave_value (v1.T1 ## scalar_value () / v2.T2 ## 
scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ()); \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTBINOP_FN (PFX ## _el_pow, T1 ## scalar, T2 ## scalar, xpow, T3, .^) \
  \
   DEFBINOP (PFX ## _el_ldiv, T1 ## scalar, T2 ## scalar) \
   { \
@@ -179,7 +252,12 @@ along with Octave; see the file COPYING.
     if (! v1.T1 ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v2.T2 ## scalar_value () / v1.T1 ## scalar_value ()); 
\
+    octave_value retval = octave_value (v2.T2 ## scalar_value () / v1.T1 ## 
scalar_value ()); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
   } \
 
 #define OCTAVE_SS_INT_BOOL_OPS(PFX, T1, T2, Z1, Z2) \
@@ -239,11 +317,11 @@ along with Octave; see the file COPYING.
 #define OCTAVE_SS_INT_OPS(TYPE) \
   OCTAVE_S_INT_UNOPS (TYPE) \
   OCTAVE_SS_POW_OPS (TYPE, TYPE) \
-  OCTAVE_SS_INT_ARITH_OPS (ss, TYPE ## _, TYPE ## _) \
-  OCTAVE_SS_INT_ARITH_OPS (ssx, TYPE ## _, ) \
-  OCTAVE_SS_INT_ARITH_OPS (sxs, , TYPE ## _) \
-  OCTAVE_SS_INT_ARITH_OPS (ssfx, TYPE ## _, float_) \
-  OCTAVE_SS_INT_ARITH_OPS (sfxs, float_, TYPE ## _) \
+  OCTAVE_SS_INT_ARITH_OPS (ss, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (ssx, TYPE ## _, , TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (sxs, , TYPE ## _, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (ssfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_SS_INT_ARITH_OPS (sfxs, float_, TYPE ## _, TYPE) \
   OCTAVE_SS_INT_CMP_OPS (ss, TYPE ## _, TYPE ## _) \
   OCTAVE_SS_INT_CMP_OPS (sx, TYPE ## _, ) \
   OCTAVE_SS_INT_CMP_OPS (xs, , TYPE ## _) \
@@ -255,12 +333,12 @@ along with Octave; see the file COPYING.
   OCTAVE_SS_INT_BOOL_OPS (sfx, TYPE ## _, float_, octave_ ## TYPE (0), 0) \
   OCTAVE_SS_INT_BOOL_OPS (fxs, float_, TYPE ## _, 0, octave_ ## TYPE (0))
 
-#define OCTAVE_SM_INT_ARITH_OPS(PFX, TS, TM) \
+#define OCTAVE_SM_INT_ARITH_OPS(PFX, TS, TM, TI) \
   /* scalar by matrix ops. */ \
  \
-  DEFNDBINOP_OP (PFX ## _add, TS ## scalar, TM ## matrix, TS ## scalar, TM ## 
array, +) \
-  DEFNDBINOP_OP (PFX ## _sub, TS ## scalar, TM ## matrix, TS ## scalar, TM ## 
array, -) \
-  DEFNDBINOP_OP (PFX ## _mul, TS ## scalar, TM ## matrix, TS ## scalar, TM ## 
array, *) \
+  DEFINTNDBINOP_OP (PFX ## _add, TS ## scalar, TM ## matrix, TS ## scalar, TM 
## array, +, TI) \
+  DEFINTNDBINOP_OP (PFX ## _sub, TS ## scalar, TM ## matrix, TS ## scalar, TM 
## array, -, TI) \
+  DEFINTNDBINOP_OP (PFX ## _mul, TS ## scalar, TM ## matrix, TS ## scalar, TM 
## array, *, TI) \
  \
   /* DEFBINOP (PFX ## _div, TS ## scalar, TM ## matrix) */ \
   /* { */ \
@@ -281,18 +359,28 @@ along with Octave; see the file COPYING.
     if (! v1.TS ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v2.TS ## scalar_value () / v1.TS ## scalar_value ()); 
\
-  } \
- \
-  DEFNDBINOP_OP (PFX ## _el_mul, TS ## scalar, TM ## matrix, TS ## scalar, TM 
## array, *) \
+    octave_value retval = octave_value (v2.TS ## scalar_value () / v1.TS ## 
scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("\\", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTNDBINOP_OP (PFX ## _el_mul, TS ## scalar, TM ## matrix, TS ## scalar, 
TM ## array, *, TI) \
   DEFBINOP (PFX ## _el_div, TS ## scalar, TM ## matrix) \
   { \
     CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## 
matrix&); \
  \
-    return octave_value (v1.TS ## scalar_value () / v2.TM ## array_value ()); \
-  } \
- \
-  DEFNDBINOP_FN (PFX ## _el_pow, TS ## scalar, TM ## matrix, TS ## scalar, TM 
## array, elem_xpow) \
+    octave_value retval = octave_value (v1.TS ## scalar_value () / v2.TM ## 
array_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_pow, TS ## scalar, TM ## matrix, TS ## scalar, 
TM ## array, elem_xpow, TI, .^) \
  \
   DEFBINOP (PFX ## _el_ldiv, TS ## scalar, TM ## matrix) \
   { \
@@ -301,7 +389,12 @@ along with Octave; see the file COPYING.
     if (! v1.TS ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v2.TM ## array_value () / v1.TS ## scalar_value ()); \
+    octave_value retval = octave_value (v2.TM ## array_value () / v1.TS ## 
scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
   }
 
 #define OCTAVE_SM_INT_CMP_OPS(PFX, TS, TM) \
@@ -388,11 +481,11 @@ along with Octave; see the file COPYING.
 
 #define OCTAVE_SM_INT_OPS(TYPE) \
   OCTAVE_SM_POW_OPS (TYPE, TYPE) \
-  OCTAVE_SM_INT_ARITH_OPS (sm, TYPE ## _, TYPE ## _) \
-  OCTAVE_SM_INT_ARITH_OPS (smx, TYPE ## _, )        \
-  OCTAVE_SM_INT_ARITH_OPS (sxm, , TYPE ## _) \
-  OCTAVE_SM_INT_ARITH_OPS (smfx, TYPE ## _, float_)         \
-  OCTAVE_SM_INT_ARITH_OPS (sfxm, float_, TYPE ## _) \
+  OCTAVE_SM_INT_ARITH_OPS (sm, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (smx, TYPE ## _, , TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (sxm, , TYPE ## _, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (smfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_SM_INT_ARITH_OPS (sfxm, float_, TYPE ## _, TYPE) \
   OCTAVE_SM_INT_CMP_OPS (sm, TYPE ## _, TYPE ## _) \
   OCTAVE_SM_INT_CMP_OPS (xm, , TYPE ## _) \
   OCTAVE_SM_INT_CMP_OPS (smx, TYPE ## _, ) \
@@ -407,12 +500,12 @@ along with Octave; see the file COPYING.
   OCTAVE_SM_CONV (TYPE ## _, complex_) \
   OCTAVE_SM_CONV (TYPE ## _, float_complex_)
 
-#define OCTAVE_MS_INT_ARITH_OPS(PFX, TM, TS) \
+#define OCTAVE_MS_INT_ARITH_OPS(PFX, TM, TS, TI) \
   /* matrix by scalar ops. */ \
  \
-  DEFNDBINOP_OP (PFX ## _add, TM ## matrix, TS ## scalar, TM ## array, TS ## 
scalar, +) \
-  DEFNDBINOP_OP (PFX ## _sub, TM ## matrix, TS ## scalar, TM ## array, TS ## 
scalar, -) \
-  DEFNDBINOP_OP (PFX ## _mul, TM ## matrix, TS ## scalar, TM ## array, TS ## 
scalar, *) \
+  DEFINTNDBINOP_OP (PFX ## _add, TM ## matrix, TS ## scalar, TM ## array, TS 
## scalar, +, TI) \
+  DEFINTNDBINOP_OP (PFX ## _sub, TM ## matrix, TS ## scalar, TM ## array, TS 
## scalar, -, TI) \
+  DEFINTNDBINOP_OP (PFX ## _mul, TM ## matrix, TS ## scalar, TM ## array, TS 
## scalar, *, TI) \
  \
   DEFBINOP (PFX ## _div, TM ## matrix, TS ## scalar) \
   { \
@@ -421,7 +514,12 @@ along with Octave; see the file COPYING.
     if (! v2.TS ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v1.TM ## array_value () / v2.TS ## scalar_value ()); \
+    octave_value retval = octave_value (v1.TM ## array_value () / v2.TS ## 
scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("/", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
   } \
  \
   /* DEFBINOP_FN (PFX ## _pow, TM ## matrix, TS ## scalar, xpow) */ \
@@ -436,7 +534,7 @@ along with Octave; see the file COPYING.
   /* return octave_value (xleftdiv (m1, m2)); */ \
   /* } */ \
  \
-  DEFNDBINOP_OP (PFX ## _el_mul, TM ## matrix, TS ## scalar, TM ## array, TS 
## scalar, *) \
+  DEFINTNDBINOP_OP (PFX ## _el_mul, TM ## matrix, TS ## scalar, TM ## array, 
TS ## scalar, *, TI) \
  \
   DEFBINOP (PFX ## _el_div, TM ## matrix, TS ## scalar) \
   { \
@@ -445,16 +543,26 @@ along with Octave; see the file COPYING.
     if (! v2.TS ## scalar_value ()) \
       gripe_divide_by_zero (); \
  \
-    return octave_value (v1.TM ## array_value () / v2.TS ## scalar_value ()); \
-  } \
- \
-  DEFNDBINOP_FN (PFX ## _el_pow, TM ## matrix, TS ## scalar, TM ## array, TS 
## scalar, elem_xpow) \
+    octave_value retval = octave_value (v1.TM ## array_value () / v2.TS ## 
scalar_value ()); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated ("./", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
+  } \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_pow, TM ## matrix, TS ## scalar, TM ## array, 
TS ## scalar, elem_xpow, TI, .^) \
  \
   DEFBINOP (PFX ## _el_ldiv, TM ## matrix, TS ## scalar) \
   { \
     CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## 
scalar&); \
     \
-    return v2.TS ## scalar_value () / v1.TM ## array_value (); \
+    octave_value retval = v2.TS ## scalar_value () / v1.TM ## array_value (); \
+    if (octave_ ## TI ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".^", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## TI ::clear_conv_flag (); \
+    return retval; \
   }
 
 #define OCTAVE_MS_INT_CMP_OPS(PFX, TM, TS) \
@@ -531,11 +639,11 @@ octave_value elem_xpow (FloatNDArray a, 
 
 #define OCTAVE_MS_INT_OPS(TYPE) \
   OCTAVE_MS_POW_OPS (TYPE, TYPE) \
-  OCTAVE_MS_INT_ARITH_OPS (ms, TYPE ## _, TYPE ## _) \
-  OCTAVE_MS_INT_ARITH_OPS (msx, TYPE ## _, ) \
-  OCTAVE_MS_INT_ARITH_OPS (mxs, , TYPE ## _)      \
-  OCTAVE_MS_INT_ARITH_OPS (msfx, TYPE ## _, float_) \
-  OCTAVE_MS_INT_ARITH_OPS (mfxs, float_, TYPE ## _)       \
+  OCTAVE_MS_INT_ARITH_OPS (ms, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (msx, TYPE ## _, , TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (mxs, , TYPE ## _, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (msfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_MS_INT_ARITH_OPS (mfxs, float_, TYPE ## _, TYPE) \
   OCTAVE_MS_INT_CMP_OPS (ms, TYPE ## _, TYPE ## _) \
   OCTAVE_MS_INT_CMP_OPS (mx, TYPE ## _, ) \
   OCTAVE_MS_INT_CMP_OPS (mxs, , TYPE ## _) \
@@ -555,7 +663,15 @@ octave_value elem_xpow (FloatNDArray a, 
  \
   DEFNDUNOP_OP (m_not, TYPE ## _matrix, TYPE ## _array, !) \
   DEFNDUNOP_OP (m_uplus, TYPE ## _matrix, TYPE ## _array, /* no-op */) \
-  DEFNDUNOP_OP (m_uminus, TYPE ## _matrix, TYPE ## _array, -) \
+  DEFUNOP (m_uminus, TYPE ## _matrix) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## TYPE ## _matrix &); \
+    octave_value retval = octave_value (- v. TYPE ## _array_value ()); \
+    if (octave_ ## TYPE ::get_math_trunc_flag ()) \
+      gripe_unop_integer_math_truncated ("-", v.type_name (). c_str ()); \
+    octave_ ## TYPE ::clear_conv_flag (); \
+    return retval; \
+  } \
  \
   DEFUNOP (m_transpose, TYPE ## _matrix) \
   { \
@@ -573,11 +689,11 @@ octave_value elem_xpow (FloatNDArray a, 
   DEFNCUNOP_METHOD (m_incr, TYPE ## _matrix, increment) \
   DEFNCUNOP_METHOD (m_decr, TYPE ## _matrix, decrement)
 
-#define OCTAVE_MM_INT_ARITH_OPS(PFX, T1, T2)   \
+#define OCTAVE_MM_INT_ARITH_OPS(PFX, T1, T2, T3)       \
   /* matrix by matrix ops. */ \
  \
-  DEFNDBINOP_OP (PFX ## _add, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## 
array, +) \
-  DEFNDBINOP_OP (PFX ## _sub, T1 ## matrix, T2 ## matrix, T1 ## array, T2 ## 
array, -) \
+  DEFINTNDBINOP_OP (PFX ## _add, T1 ## matrix, T2 ## matrix, T1 ## array, T2 
## array, +, T3) \
+  DEFINTNDBINOP_OP (PFX ## _sub, T1 ## matrix, T2 ## matrix, T1 ## array, T2 
## array, -, T3) \
  \
   /* DEFBINOP_OP (PFX ## _mul, T1 ## matrix, T2 ## matrix, *) */ \
   /* DEFBINOP_FN (PFX ## _div, T1 ## matrix, T2 ## matrix, xdiv) */ \
@@ -590,17 +706,22 @@ octave_value elem_xpow (FloatNDArray a, 
  \
   /* DEFBINOP_FN (PFX ## _ldiv, T1 ## matrix, T2 ## matrix, xleftdiv) */ \
  \
-  DEFNDBINOP_FN (PFX ## _el_mul, T1 ## matrix, T2 ## matrix, T1 ## array, T2 
## array, product) \
- \
-  DEFNDBINOP_FN (PFX ## _el_div, T1 ## matrix, T2 ## matrix, T1 ## array, T2 
## array, quotient) \
- \
-  DEFNDBINOP_FN (PFX ## _el_pow, T1 ## matrix, T2 ## matrix, T1 ## array, T2 
## array, elem_xpow) \
+  DEFINTNDBINOP_FN (PFX ## _el_mul, T1 ## matrix, T2 ## matrix, T1 ## array, 
T2 ## array, product, T3, .*) \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_div, T1 ## matrix, T2 ## matrix, T1 ## array, 
T2 ## array, quotient, T3, ./) \
+ \
+  DEFINTNDBINOP_FN (PFX ## _el_pow, T1 ## matrix, T2 ## matrix, T1 ## array, 
T2 ## array, elem_xpow, T3, .^) \
  \
   DEFBINOP (PFX ## _el_ldiv, T1 ## matrix, T2 ## matrix) \
   { \
     CAST_BINOP_ARGS (const octave_ ## T1 ## matrix&, const octave_ ## T2 ## 
matrix&); \
     \
-     return octave_value (quotient (v2.T2 ## array_value (), v1.T1 ## 
array_value ())); \
+    octave_value retval = octave_value (quotient (v2.T2 ## array_value (), 
v1.T1 ## array_value ())); \
+    if (octave_ ## T3 ::get_math_trunc_flag ()) \
+      gripe_binop_integer_math_truncated (".\\", v1.type_name (). c_str (), \
+                                         v2.type_name (). c_str ());   \
+    octave_ ## T3 ::clear_conv_flag (); \
+    return retval; \
   }
 
 #define OCTAVE_MM_INT_CMP_OPS(PFX, T1, T2) \
@@ -726,11 +847,11 @@ octave_value elem_xpow (FloatNDArray a, 
 #define OCTAVE_MM_INT_OPS(TYPE) \
   OCTAVE_M_INT_UNOPS (TYPE) \
   OCTAVE_MM_POW_OPS (TYPE, TYPE) \
-  OCTAVE_MM_INT_ARITH_OPS (mm, TYPE ## _, TYPE ## _)   \
-  OCTAVE_MM_INT_ARITH_OPS (mmx, TYPE ## _, )   \
-  OCTAVE_MM_INT_ARITH_OPS (mxm, , TYPE ## _)      \
-  OCTAVE_MM_INT_ARITH_OPS (mmfx, TYPE ## _, float_)    \
-  OCTAVE_MM_INT_ARITH_OPS (mfxm, float_, TYPE ## _)       \
+  OCTAVE_MM_INT_ARITH_OPS (mm, TYPE ## _, TYPE ## _, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mmx, TYPE ## _, , TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mxm, , TYPE ## _, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mmfx, TYPE ## _, float_, TYPE) \
+  OCTAVE_MM_INT_ARITH_OPS (mfxm, float_, TYPE ## _, TYPE) \
   OCTAVE_MM_INT_CMP_OPS (mm, TYPE ## _, TYPE ## _) \
   OCTAVE_MM_INT_CMP_OPS (mmx, TYPE ## _, ) \
   OCTAVE_MM_INT_CMP_OPS (mfxm, float_, TYPE ## _) \
diff --git a/src/error.cc b/src/error.cc
--- a/src/error.cc
+++ b/src/error.cc
@@ -1396,6 +1396,10 @@ initialize_default_warning_state (void)
   disable_warning ("Octave:str-to-num");
   disable_warning ("Octave:string-concat");
   disable_warning ("Octave:variable-switch-label");
+  disable_warning ("Octave:int-convert-nan");
+  disable_warning ("Octave:int-convert-non-int-val");
+  disable_warning ("Octave:int-convert-overflow");
+  disable_warning ("Octave:int-math-overflow");
 }
 
 DEFUN (lasterror, args, ,
diff --git a/src/gripes.cc b/src/gripes.cc
--- a/src/gripes.cc
+++ b/src/gripes.cc
@@ -213,12 +213,42 @@ gripe_truncated_conversion (const char *
 }
 
 void
+gripe_binop_integer_math_truncated (const char *op, const char *type1, const 
char *type2)
+{
+  warning_with_id ("Octave:int-math-overflow",
+                   "data truncated for %s by %s binary operator %s",
+                   type1, type2, op);
+}
+
+void
+gripe_unop_integer_math_truncated (const char* op, const char *type)
+{
+  warning_with_id ("Octave:int-math-overflow",
+                   "data truncated for the %s unary operator %s", type, op);
+}
+
+void
 gripe_library_execution_error (void)
 {
   octave_exception_state = octave_no_exception;
 
   if (! error_state)
     error ("caught execution error in library function");
+}
+
+void
+gripe_non_integer_conversion (const char *srctype, const char *desttype)
+{
+  warning_with_id ("Octave:int-convert-non-int-val", 
+                   "Conversion of non-integer value from %s to %s",
+                   srctype, desttype);
+}
+void
+gripe_nan_conversion (const char *srctype, const char *desttype)
+{
+  warning_with_id ("Octave:int-convert-nan", 
+                   "Conversion of NaN from %s to %s",
+                   srctype, desttype);
 }
 
 /*
diff --git a/src/gripes.h b/src/gripes.h
--- a/src/gripes.h
+++ b/src/gripes.h
@@ -111,6 +111,18 @@ gripe_truncated_conversion (const char *
 gripe_truncated_conversion (const char *srctype, const char *desttype);
 
 extern OCTINTERP_API void
+gripe_binop_integer_math_truncated (const char *op, const char *type1, const 
char *type2);
+
+extern OCTINTERP_API void
+gripe_unop_integer_math_truncated (const char *op, const char *type);
+
+extern OCTINTERP_API void
+gripe_non_integer_conversion (const char *srctype, const char *desttype);
+
+extern OCTINTERP_API void
+gripe_nan_conversion (const char *srctype, const char *desttype);
+
+extern OCTINTERP_API void
 gripe_divide_by_zero (void);
 
 extern OCTINTERP_API void
diff --git a/src/ov-intx.h b/src/ov-intx.h
--- a/src/ov-intx.h
+++ b/src/ov-intx.h
@@ -74,15 +74,12 @@ private:
     {
       typedef typename IM::element_type dest_el_type;
       typedef OCTAVE_INT_NDARRAY_T::element_type src_el_type;
-      dest_el_type::clear_trunc_flag ();
+      dest_el_type::clear_conv_flag ();
       IM retval (matrix);
       if (dest_el_type::get_trunc_flag ())
-        {
-          gripe_truncated_conversion (src_el_type::type_name (),
-                                      dest_el_type::type_name ());
-          dest_el_type::clear_trunc_flag ();
-        }
-
+       gripe_truncated_conversion (src_el_type::type_name (),
+                                   dest_el_type::type_name ());
+      dest_el_type::clear_conv_flag ();
       return retval;
     }
 
@@ -301,9 +298,22 @@ public:
     return retval;
   }
 
-  void increment (void) { matrix += 1; }
-
-  void decrement (void) { matrix -= 1; }
+  void increment (void) 
+   { 
+     matrix += 1; 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("++", type_name (). c_str ());
+
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
+
+  void decrement (void)
+   { 
+     matrix -= 1; 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("--", type_name (). c_str ());
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
 
   idx_vector index_vector (void) const { return idx_vector (matrix); }
 
@@ -433,16 +443,13 @@ private:
     {
       typedef IS dest_el_type;
       typedef OCTAVE_INT_T src_el_type;
-      dest_el_type::clear_trunc_flag ();
+      dest_el_type::clear_conv_flag ();
       IS retval (scalar);
+
       if (dest_el_type::get_trunc_flag ())
-        {
-          gripe_truncated_conversion (src_el_type::type_name (),
-                                      dest_el_type::type_name ());
-          dest_el_type::clear_trunc_flag ();
-
-        }
-
+       gripe_truncated_conversion (src_el_type::type_name (),
+                                   dest_el_type::type_name ());
+      dest_el_type::clear_conv_flag ();
       return retval;
     }
 
@@ -615,9 +622,21 @@ public:
     return retval;
   }
 
-  void increment (void) { scalar += 1; }
-
-  void decrement (void) { scalar -= 1; }
+  void increment (void) 
+   { 
+     scalar += 1; 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("++", type_name (). c_str ());
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
+
+  void decrement (void)
+   { 
+     scalar -= 1; 
+     if (OCTAVE_INT_T::get_math_trunc_flag ())
+       gripe_unop_integer_math_truncated ("--", type_name (). c_str ());
+      OCTAVE_INT_T::clear_conv_flag ();
+   }
 
   idx_vector index_vector (void) const { return idx_vector (scalar); }
 
diff --git a/src/ov.cc b/src/ov.cc
--- a/src/ov.cc
+++ b/src/ov.cc
@@ -1368,14 +1368,14 @@ convert_to_int_array (const Array<octave
   Array<int> retval (A.dims ());
   octave_idx_type n = A.numel ();
 
-  octave_int<int>::clear_trunc_flag ();
+  octave_int<int>::clear_conv_flag ();
   for (octave_idx_type i = 0; i < n; i++)
     retval.xelem (i) = octave_int<int> (A.xelem (i));
+
   if (octave_int<int>::get_trunc_flag ())
-    {
-      gripe_truncated_conversion (octave_int<T>::type_name (), "int");
-      octave_int<int>::clear_trunc_flag ();
-    }
+    gripe_truncated_conversion (octave_int<T>::type_name (), "int");
+
+  octave_int<int>::clear_conv_flag ();
 
   return retval;
 }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]