[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Add additional integer math and conversion warnings and the intwarning f
From: |
David Bateman |
Subject: |
Add additional integer math and conversion warnings and the intwarning function |
Date: |
Mon, 18 Aug 2008 18:11:40 +0200 |
User-agent: |
Thunderbird 2.0.0.16 (X11/20080725) |
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
--
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 1219075546 -7200
# Node ID 8c919c2a80883e2b2909a200225275b74ebc07d5
# 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-18 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-18 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>
+
+ * 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,34 @@ 2008-08-12 John W. Eaton <address@hidden
+2008-08-18 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_math_truncated_conversion (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_math_truncated_conversion (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_math_truncated_conversion (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_math_truncated_conversion (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) \
+ 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_math_truncated_conversion (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) \
+ 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_math_truncated_conversion (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,28 @@ 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_math_truncated_conversion (v.type_name (). c_str (), \
+ 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 +202,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_math_truncated_conversion (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 +219,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_math_truncated_conversion (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 +236,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_math_truncated_conversion (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 +253,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_math_truncated_conversion (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 +318,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 +334,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 +360,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_math_truncated_conversion (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_math_truncated_conversion (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 +390,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_math_truncated_conversion (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 +482,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 +501,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 +515,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_math_truncated_conversion (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 +535,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 +544,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_math_truncated_conversion (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_math_truncated_conversion (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 +640,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 +664,16 @@ 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_math_truncated_conversion (v.type_name (). c_str (), \
+ v.type_name (). c_str ()); \
+ octave_ ## TYPE ::clear_conv_flag (); \
+ return retval; \
+ } \
\
DEFUNOP (m_transpose, TYPE ## _matrix) \
{ \
@@ -573,11 +691,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 +708,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_math_truncated_conversion (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 +849,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,35 @@ gripe_truncated_conversion (const char *
}
void
+gripe_math_truncated_conversion (const char *srctype, const char *desttype)
+{
+ warning_with_id ("Octave:int-math-overflow",
+ "data truncated converting from %s to %s",
+ srctype, desttype);
+}
+
+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,15 @@ gripe_truncated_conversion (const char *
gripe_truncated_conversion (const char *srctype, const char *desttype);
extern OCTINTERP_API void
+gripe_math_truncated_conversion (const char *srctype, const char *desttype);
+
+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,23 @@ 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_math_truncated_conversion (type_name (). c_str (),
+ type_name (). c_str ());
+ OCTAVE_INT_T::clear_conv_flag ();
+ }
+
+ void decrement (void)
+ {
+ matrix -= 1;
+ if (OCTAVE_INT_T::get_math_trunc_flag ())
+ gripe_math_truncated_conversion (type_name (). c_str (),
+ type_name (). c_str ());
+ OCTAVE_INT_T::clear_conv_flag ();
+ }
idx_vector index_vector (void) const { return idx_vector (matrix); }
@@ -433,16 +444,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 +623,23 @@ 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_math_truncated_conversion (type_name (). c_str (),
+ type_name (). c_str ());
+ OCTAVE_INT_T::clear_conv_flag ();
+ }
+
+ void decrement (void)
+ {
+ scalar -= 1;
+ if (OCTAVE_INT_T::get_math_trunc_flag ())
+ gripe_math_truncated_conversion (type_name (). c_str (),
+ 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;
}
- Add additional integer math and conversion warnings and the intwarning function,
David Bateman <=