# HG changeset patch # User John W. Eaton # Date 1215802590 14400 # Node ID 935be827eaf8fbbb44f7eb34a5951a893e436724 # Parent fcc70f30fe31cd4bc694ce773df17bb69131f8c1 error for NaN values in & and | expressions diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/Array-util.cc --- a/liboctave/Array-util.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/Array-util.cc Fri Jul 11 14:56:30 2008 -0400 @@ -480,6 +480,11 @@ return pva->pidx > pvb->pidx; } +void +gripe_nan_to_logical_conversion (void) +{ + (*current_liboctave_error_handler) ("invalid conversion of NaN to logical"); +} void gripe_nonconformant (const char *op, int op1_len, int op2_len) diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/Array-util.h --- a/liboctave/Array-util.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/Array-util.h Fri Jul 11 14:56:30 2008 -0400 @@ -89,6 +89,8 @@ extern int OCTAVE_API permute_vector_compare (const void *a, const void *b); +extern void OCTAVE_API gripe_nan_to_logical_conversion (void); + extern void OCTAVE_API gripe_nonconformant (const char *op, int op1_len, int op2_len); extern void OCTAVE_API gripe_nonconformant (const char *op, int op1_nr, int op1_nc, diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/CMatrix.cc --- a/liboctave/CMatrix.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/CMatrix.cc Fri Jul 11 14:56:30 2008 -0400 @@ -3302,6 +3302,23 @@ } bool +ComplexMatrix::any_element_is_nan (void) const +{ + octave_idx_type nr = rows (); + octave_idx_type nc = cols (); + + for (octave_idx_type j = 0; j < nc; j++) + for (octave_idx_type i = 0; i < nr; i++) + { + Complex val = elem (i, j); + if (xisnan (val)) + return true; + } + + return false; +} + +bool ComplexMatrix::any_element_is_inf_or_nan (void) const { octave_idx_type nr = rows (); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/CMatrix.h --- a/liboctave/CMatrix.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/CMatrix.h Fri Jul 11 14:56:30 2008 -0400 @@ -327,6 +327,7 @@ ComplexMatrix map (cmapper fcn) const; boolMatrix map (bmapper fcn) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool all_elements_are_real (void) const; bool all_integers (double& max_val, double& min_val) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/CNDArray.cc --- a/liboctave/CNDArray.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/CNDArray.cc Fri Jul 11 14:56:30 2008 -0400 @@ -497,6 +497,20 @@ // FIXME -- this is not quite the right thing. bool +ComplexNDArray::any_element_is_nan (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + { + Complex val = elem (i); + if (xisnan (val)) + return true; + } + return false; +} + +bool ComplexNDArray::any_element_is_inf_or_nan (void) const { octave_idx_type nel = nelem (); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/CNDArray.h --- a/liboctave/CNDArray.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/CNDArray.h Fri Jul 11 14:56:30 2008 -0400 @@ -64,6 +64,7 @@ // FIXME -- this is not quite the right thing. + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool all_elements_are_real (void) const; bool all_integers (double& max_val, double& min_val) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/CSparse.cc --- a/liboctave/CSparse.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/CSparse.cc Fri Jul 11 14:56:30 2008 -0400 @@ -7179,6 +7179,21 @@ // other operations bool +SparseComplexMatrix::any_element_is_nan (void) const +{ + octave_idx_type nel = nnz (); + + for (octave_idx_type i = 0; i < nel; i++) + { + Complex val = data (i); + if (xisnan (val)) + return true; + } + + return false; +} + +bool SparseComplexMatrix::any_element_is_inf_or_nan (void) const { octave_idx_type nel = nnz (); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/CSparse.h --- a/liboctave/CSparse.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/CSparse.h Fri Jul 11 14:56:30 2008 -0400 @@ -402,6 +402,7 @@ SparseComplexMatrix ipermute (const Array& vec) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool all_elements_are_real (void) const; bool all_integers (double& max_val, double& min_val) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/ChangeLog --- a/liboctave/ChangeLog Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/ChangeLog Fri Jul 11 14:56:30 2008 -0400 @@ -1,3 +1,19 @@ +2008-07-11 John W. Eaton + + * mx-op-defs.h (MS_BOOL_OP, SM_BOOL_OP, MM_BOOL_OP, NDS_BOOL_OP, + SND_BOOL_OP, NDND_BOOL_OP): Detect NaN values. + * Array-util.cc (gripe_nan_to_logical_conversion): New function. + * Array-util.h: Provide decl. + * oct-inttypes.h (xisnan (octave_int)): New function. + * lo-mappers.h (xisnan (bool), xisnan (char)): New inline functions. + + * CMatrix.cc, CNDArray.cc, CSparse.cc, dMatrix.cc, dNDArray.cc, + dSparse.cc, fCMatrix.cc, fCNDArray.cc, fMatrix.cc, fNDArray.cc: + New member function, any_element_is_nan. + * CMatrix.h, CNDArray.h, CSparse.h, dMatrix.h, dNDArray.h, + dSparse.h, fCMatrix.h, fCNDArray.h, fMatrix.h, fNDArray.h: + Provide decl. + 2008-07-10 David Bateman * dNDArray.cc (NDArray::NDArray (const Array&, diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/dMatrix.cc --- a/liboctave/dMatrix.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/dMatrix.cc Fri Jul 11 14:56:30 2008 -0400 @@ -2849,6 +2849,20 @@ return false; } +bool +Matrix::any_element_is_nan (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + { + double val = elem (i); + if (xisnan (val)) + return true; + } + + return false; +} bool Matrix::any_element_is_inf_or_nan (void) const diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/dMatrix.h --- a/liboctave/dMatrix.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/dMatrix.h Fri Jul 11 14:56:30 2008 -0400 @@ -282,6 +282,7 @@ boolMatrix map (bmapper fcn) const; bool any_element_is_negative (bool = false) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const; bool all_elements_are_int_or_inf_or_nan (void) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/dNDArray.cc --- a/liboctave/dNDArray.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/dNDArray.cc Fri Jul 11 14:56:30 2008 -0400 @@ -556,6 +556,20 @@ return false; } +bool +NDArray::any_element_is_nan (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + { + double val = elem (i); + if (xisnan (val)) + return true; + } + + return false; +} bool NDArray::any_element_is_inf_or_nan (void) const diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/dNDArray.h --- a/liboctave/dNDArray.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/dNDArray.h Fri Jul 11 14:56:30 2008 -0400 @@ -70,6 +70,7 @@ boolNDArray operator ! (void) const; bool any_element_is_negative (bool = false) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const; bool all_elements_are_zero (void) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/dSparse.cc --- a/liboctave/dSparse.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/dSparse.cc Fri Jul 11 14:56:30 2008 -0400 @@ -7237,6 +7237,21 @@ } bool +SparseMatrix::any_element_is_nan (void) const +{ + octave_idx_type nel = nnz (); + + for (octave_idx_type i = 0; i < nel; i++) + { + double val = data (i); + if (xisnan (val)) + return true; + } + + return false; +} + +bool SparseMatrix::any_element_is_inf_or_nan (void) const { octave_idx_type nel = nnz (); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/dSparse.h --- a/liboctave/dSparse.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/dSparse.h Fri Jul 11 14:56:30 2008 -0400 @@ -372,6 +372,7 @@ // other operations bool any_element_is_negative (bool = false) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool all_elements_are_zero (void) const; bool all_elements_are_int_or_inf_or_nan (void) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fCMatrix.cc --- a/liboctave/fCMatrix.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fCMatrix.cc Fri Jul 11 14:56:30 2008 -0400 @@ -3295,6 +3295,23 @@ } bool +FloatComplexMatrix::any_element_is_nan (void) const +{ + octave_idx_type nr = rows (); + octave_idx_type nc = cols (); + + for (octave_idx_type j = 0; j < nc; j++) + for (octave_idx_type i = 0; i < nr; i++) + { + FloatComplex val = elem (i, j); + if (xisnan (val)) + return true; + } + + return false; +} + +bool FloatComplexMatrix::any_element_is_inf_or_nan (void) const { octave_idx_type nr = rows (); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fCMatrix.h --- a/liboctave/fCMatrix.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fCMatrix.h Fri Jul 11 14:56:30 2008 -0400 @@ -327,6 +327,7 @@ FloatComplexMatrix map (cmapper fcn) const; boolMatrix map (bmapper fcn) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool all_elements_are_real (void) const; bool all_integers (float& max_val, float& min_val) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fCNDArray.cc --- a/liboctave/fCNDArray.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fCNDArray.cc Fri Jul 11 14:56:30 2008 -0400 @@ -492,6 +492,20 @@ // FIXME -- this is not quite the right thing. bool +FloatComplexNDArray::any_element_is_nan (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + { + FloatComplex val = elem (i); + if (xisnan (val)) + return true; + } + return false; +} + +bool FloatComplexNDArray::any_element_is_inf_or_nan (void) const { octave_idx_type nel = nelem (); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fCNDArray.h --- a/liboctave/fCNDArray.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fCNDArray.h Fri Jul 11 14:56:30 2008 -0400 @@ -64,6 +64,7 @@ // FIXME -- this is not quite the right thing. + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool all_elements_are_real (void) const; bool all_integers (float& max_val, float& min_val) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fMatrix.cc --- a/liboctave/fMatrix.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fMatrix.cc Fri Jul 11 14:56:30 2008 -0400 @@ -2848,6 +2848,20 @@ return false; } +bool +FloatMatrix::any_element_is_nan (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + { + float val = elem (i); + if (xisnan (val)) + return true; + } + + return false; +} bool FloatMatrix::any_element_is_inf_or_nan (void) const diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fMatrix.h --- a/liboctave/fMatrix.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fMatrix.h Fri Jul 11 14:56:30 2008 -0400 @@ -282,6 +282,7 @@ boolMatrix map (bmapper fcn) const; bool any_element_is_negative (bool = false) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const; bool all_elements_are_int_or_inf_or_nan (void) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fNDArray.cc --- a/liboctave/fNDArray.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fNDArray.cc Fri Jul 11 14:56:30 2008 -0400 @@ -514,6 +514,20 @@ return false; } +bool +FloatNDArray::any_element_is_nan (void) const +{ + octave_idx_type nel = nelem (); + + for (octave_idx_type i = 0; i < nel; i++) + { + float val = elem (i); + if (xisnan (val)) + return true; + } + + return false; +} bool FloatNDArray::any_element_is_inf_or_nan (void) const diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/fNDArray.h --- a/liboctave/fNDArray.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/fNDArray.h Fri Jul 11 14:56:30 2008 -0400 @@ -67,6 +67,7 @@ boolNDArray operator ! (void) const; bool any_element_is_negative (bool = false) const; + bool any_element_is_nan (void) const; bool any_element_is_inf_or_nan (void) const; bool any_element_not_one_or_zero (void) const; bool all_elements_are_zero (void) const; diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/lo-mappers.h --- a/liboctave/lo-mappers.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/lo-mappers.h Fri Jul 11 14:56:30 2008 -0400 @@ -42,6 +42,10 @@ extern OCTAVE_API Complex xlog2 (const Complex& x, int& exp); extern OCTAVE_API double xexp2 (double x); +// These are used by the BOOL_OP macros in mx-op-defs.h. +inline bool xisnan (bool) { return false; } +inline bool xisnan (char) { return false; } + extern OCTAVE_API bool xisnan (double x); extern OCTAVE_API bool xfinite (double x); extern OCTAVE_API bool xisinf (double x); diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/mx-op-defs.h --- a/liboctave/mx-op-defs.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/mx-op-defs.h Fri Jul 11 14:56:30 2008 -0400 @@ -228,9 +228,21 @@ { \ r.resize (nr, nc); \ \ - for (int j = 0; j < nc; j++) \ - for (int i = 0; i < nr; i++) \ - r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \ + if (xisnan (s)) \ + gripe_nan_to_logical_conversion (); \ + else \ + { \ + \ + for (int j = 0; j < nc; j++) \ + for (int i = 0; i < nr; i++) \ + if (xisnan (m.elem(i, j))) \ + { \ + gripe_nan_to_logical_conversion (); \ + return r; \ + } \ + else \ + r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \ + } \ } \ \ return r; \ @@ -331,9 +343,20 @@ { \ r.resize (nr, nc); \ \ - for (int j = 0; j < nc; j++) \ - for (int i = 0; i < nr; i++) \ - r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \ + if (xisnan (s)) \ + gripe_nan_to_logical_conversion (); \ + else \ + { \ + for (int j = 0; j < nc; j++) \ + for (int i = 0; i < nr; i++) \ + if (xisnan (m.elem(i, j))) \ + { \ + gripe_nan_to_logical_conversion (); \ + return r; \ + } \ + else \ + r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \ + } \ } \ \ return r; \ @@ -456,8 +479,14 @@ \ for (int j = 0; j < m1_nc; j++) \ for (int i = 0; i < m1_nr; i++) \ - r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \ - OP (m2.elem(i, j) != RHS_ZERO); \ + if (xisnan (m1.elem(i, j)) || xisnan (m2.elem(i, j))) \ + { \ + gripe_nan_to_logical_conversion (); \ + return r; \ + } \ + else \ + r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \ + OP (m2.elem(i, j) != RHS_ZERO); \ } \ } \ else \ @@ -605,8 +634,19 @@ { \ r.resize (m.dims ()); \ \ - for (int i = 0; i < len; i++) \ - r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \ + if (xisnan (s)) \ + gripe_nan_to_logical_conversion (); \ + else \ + { \ + for (int i = 0; i < len; i++) \ + if (xisnan (m.elem(i))) \ + { \ + gripe_nan_to_logical_conversion (); \ + return r; \ + } \ + else \ + r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \ + } \ } \ \ return r; \ @@ -748,8 +788,19 @@ { \ r.resize (m.dims ()); \ \ - for (int i = 0; i < len; i++) \ - r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \ + if (xisnan (s)) \ + gripe_nan_to_logical_conversion (); \ + else \ + { \ + for (int i = 0; i < len; i++) \ + if (xisnan (m.elem(i))) \ + { \ + gripe_nan_to_logical_conversion (); \ + return r; \ + } \ + else \ + r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \ + } \ } \ \ return r; \ @@ -863,7 +914,13 @@ r.resize (m1_dims); \ \ for (int i = 0; i < m1.length (); i++) \ - r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); \ + if (xisnan (m1.elem(i)) || xisnan (m2.elem(i))) \ + { \ + gripe_nan_to_logical_conversion (); \ + return r; \ + } \ + else \ + r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); \ } \ } \ else \ diff -r fcc70f30fe31 -r 935be827eaf8 liboctave/oct-inttypes.h --- a/liboctave/oct-inttypes.h Thu Jul 10 17:36:20 2008 -0400 +++ b/liboctave/oct-inttypes.h Fri Jul 11 14:56:30 2008 -0400 @@ -408,6 +408,13 @@ }; template +bool +xisnan (const octave_int&) +{ + return false; +} + +template octave_int pow (const octave_int& a, const octave_int& b) { diff -r fcc70f30fe31 -r 935be827eaf8 scripts/general/logical.m --- a/scripts/general/logical.m Thu Jul 10 17:36:20 2008 -0400 +++ b/scripts/general/logical.m Fri Jul 11 14:56:30 2008 -0400 @@ -42,7 +42,11 @@ elseif (isempty (x)) y = zeros (size (x), "logical"); elseif (isnumeric (x)) - y = x != 0; + if (any (isnan (x(:)))) + error ("invalid conversion from NaN to logical"); + else + y = x != 0; + endif else error ("logical not defined for type `%s'", typeinfo (x)); endif @@ -59,4 +63,6 @@ %!assert (logical (-13), true); %!assert (logical (int8 (13)), true); %!assert (logical (int8 (-13)), true); -%!assert (logical ([-1, 0, 1, NaN, Inf]), [-1, 0, 1, NaN, Inf] != 0); +%!assert (logical ([-1, 0, 1, Inf]), [-1, 0, 1, Inf] != 0); +%!error (logical ([-1, 0, 1, NaN, Inf])) +%!error (logical (NaN)) diff -r fcc70f30fe31 -r 935be827eaf8 src/ChangeLog --- a/src/ChangeLog Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ChangeLog Fri Jul 11 14:56:30 2008 -0400 @@ -1,3 +1,13 @@ +2008-07-11 John W. Eaton + + * ov-float.h, ov-flt-re-mat.cc, ov-range.h, ov-re-mat.h, + ov-re-sparse.cc, ov-scalar.h: Check for NaN in bool_value and + bool_array_value member functions to bool. + + * ops.h (DEFSCALARBOOLOP_OP): New macro. + * OPERATORS/op-s-s.cc, OPERATORS/op-fs-fs.cc: Use it to define + el_and and el_or ops. + 2008-07-10 David Bateman * DLD-FUNCTIONS/lookup.cc (assign): Delete. diff -r fcc70f30fe31 -r 935be827eaf8 src/OPERATORS/op-fs-fs.cc --- a/src/OPERATORS/op-fs-fs.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/src/OPERATORS/op-fs-fs.cc Fri Jul 11 14:56:30 2008 -0400 @@ -114,8 +114,8 @@ return octave_value (v2.float_value () / d); } -DEFBINOP_OP (el_and, float_scalar, float_scalar, &&) -DEFBINOP_OP (el_or, float_scalar, float_scalar, ||) +DEFSCALARBOOLOP_OP (el_and, float_scalar, float_scalar, &&) +DEFSCALARBOOLOP_OP (el_or, float_scalar, float_scalar, ||) DEFNDCATOP_FN (fs_fs, float_scalar, float_scalar, float_array, float_array, concat) DEFNDCATOP_FN (s_fs, scalar, float_scalar, float_array, float_array, concat) diff -r fcc70f30fe31 -r 935be827eaf8 src/OPERATORS/op-s-s.cc --- a/src/OPERATORS/op-s-s.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/src/OPERATORS/op-s-s.cc Fri Jul 11 14:56:30 2008 -0400 @@ -115,8 +115,8 @@ return octave_value (v2.double_value () / d); } -DEFBINOP_OP (el_and, scalar, scalar, &&) -DEFBINOP_OP (el_or, scalar, scalar, ||) +DEFSCALARBOOLOP_OP (el_and, scalar, scalar, &&) +DEFSCALARBOOLOP_OP (el_or, scalar, scalar, ||) DEFNDCATOP_FN (s_s, scalar, scalar, array, array, concat) diff -r fcc70f30fe31 -r 935be827eaf8 src/ops.h --- a/src/ops.h Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ops.h Fri Jul 11 14:56:30 2008 -0400 @@ -293,6 +293,20 @@ (v1.t1 ## _value () op v2.t2 ## _value ()); \ } +#define DEFSCALARBOOLOP_OP(name, t1, t2, op) \ + BINOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + if (xisnan (v1.t1 ## _value ()) || xisnan (v2.t2 ## _value ())) \ + { \ + error ("invalid conversion from NaN to logical"); \ + return octave_value (); \ + } \ + else \ + return octave_value \ + (v1.t1 ## _value () op v2.t2 ## _value ()); \ + } + #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \ BINOPDECL (name, a1, a2) \ { \ diff -r fcc70f30fe31 -r 935be827eaf8 src/ov-float.h --- a/src/ov-float.h Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ov-float.h Fri Jul 11 14:56:30 2008 -0400 @@ -191,7 +191,9 @@ bool bool_value (bool warn = false) const { - if (warn && scalar != 0 && scalar != 1) + if (xisnan (scalar)) + error ("invalid conversion from NaN to logical"); + else if (warn && scalar != 0 && scalar != 1) gripe_logical_conversion (); return scalar; @@ -199,7 +201,9 @@ boolNDArray bool_array_value (bool warn = false) const { - if (warn && scalar != 0 && scalar != 1) + if (xisnan (scalar)) + error ("invalid conversion from NaN to logical"); + else if (warn && scalar != 0 && scalar != 1) gripe_logical_conversion (); return boolNDArray (dim_vector (1, 1), scalar); diff -r fcc70f30fe31 -r 935be827eaf8 src/ov-flt-re-mat.cc --- a/src/ov-flt-re-mat.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ov-flt-re-mat.cc Fri Jul 11 14:56:30 2008 -0400 @@ -218,7 +218,9 @@ boolNDArray octave_float_matrix::bool_array_value (bool warn) const { - if (warn && matrix.any_element_not_one_or_zero ()) + if (matrix.any_element_is_nan ()) + error ("invalid conversion from NaN to logical"); + else if (warn && matrix.any_element_not_one_or_zero ()) gripe_logical_conversion (); return boolNDArray (matrix); diff -r fcc70f30fe31 -r 935be827eaf8 src/ov-range.h --- a/src/ov-range.h Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ov-range.h Fri Jul 11 14:56:30 2008 -0400 @@ -227,7 +227,9 @@ { Matrix m = range.matrix_value (); - if (warn && m.any_element_not_one_or_zero ()) + if (m.any_element_is_nan ()) + error ("invalid conversion from NaN to logical"); + else if (warn && m.any_element_not_one_or_zero ()) gripe_logical_conversion (); return boolNDArray (m); diff -r fcc70f30fe31 -r 935be827eaf8 src/ov-re-mat.cc --- a/src/ov-re-mat.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ov-re-mat.cc Fri Jul 11 14:56:30 2008 -0400 @@ -224,7 +224,9 @@ boolNDArray octave_matrix::bool_array_value (bool warn) const { - if (warn && matrix.any_element_not_one_or_zero ()) + if (matrix.any_element_is_nan ()) + error ("invalid conversion from NaN to logical"); + else if (warn && matrix.any_element_not_one_or_zero ()) gripe_logical_conversion (); return boolNDArray (matrix); diff -r fcc70f30fe31 -r 935be827eaf8 src/ov-re-sparse.cc --- a/src/ov-re-sparse.cc Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ov-re-sparse.cc Fri Jul 11 14:56:30 2008 -0400 @@ -150,7 +150,9 @@ { NDArray m = matrix.matrix_value (); - if (warn && m.any_element_not_one_or_zero ()) + if (m.any_element_is_nan ()) + error ("invalid conversion from NaN to logical"); + else if (warn && m.any_element_not_one_or_zero ()) gripe_logical_conversion (); return boolNDArray (m); diff -r fcc70f30fe31 -r 935be827eaf8 src/ov-scalar.h --- a/src/ov-scalar.h Thu Jul 10 17:36:20 2008 -0400 +++ b/src/ov-scalar.h Fri Jul 11 14:56:30 2008 -0400 @@ -192,7 +192,9 @@ bool bool_value (bool warn = false) const { - if (warn && scalar != 0 && scalar != 1) + if (xisnan (scalar)) + error ("invalid conversion from NaN to logical"); + else if (warn && scalar != 0 && scalar != 1) gripe_logical_conversion (); return scalar; @@ -200,7 +202,9 @@ boolNDArray bool_array_value (bool warn = false) const { - if (warn && scalar != 0 && scalar != 1) + if (xisnan (scalar)) + error ("invalid conversion from NaN to logical"); + else if (warn && scalar != 0 && scalar != 1) gripe_logical_conversion (); return boolNDArray (dim_vector (1, 1), scalar);