# HG changeset patch # User jwe # Date 1028874736 0 # Node ID cfb762dc92595fb31c7b6cd06105dc8e9a9e9bed # Parent 00d06e24cc8900f64eb799cdae9c2389ea5bb2ca [project @ 2002-08-09 06:32:15 by jwe] diff -r 00d06e24cc89 -r cfb762dc9259 liboctave/ChangeLog --- a/liboctave/ChangeLog Wed Aug 07 07:11:44 2002 +0000 +++ b/liboctave/ChangeLog Fri Aug 09 06:32:16 2002 +0000 @@ -1,3 +1,14 @@ +2002-08-08 John W. Eaton + + * lo-ieee.cc (lo_ieee_is_NA): New function. + (lo_ieee_is_NaN_or_NA): New function. + (octave_NA): New global value. + (octave_ieee_init): Initialize it. + * lo-mappers.cc (octave_is_NA): New function. + (octave_is_NaN_or_NA): New function. + (xisnan): Return false if NaN looks like a missing value. + (xisnan (const Complex&)): Use xisnan here. + 2002-08-02 John W. Eaton * CMatrix.h (ComplexMatrix::all, ComplexMatrix::any, diff -r 00d06e24cc89 -r cfb762dc9259 liboctave/lo-ieee.cc --- a/liboctave/lo-ieee.cc Wed Aug 07 07:11:44 2002 +0000 +++ b/liboctave/lo-ieee.cc Fri Aug 09 06:32:16 2002 +0000 @@ -46,6 +46,7 @@ #endif #include "lo-ieee.h" +#include "mach-info.h" // Octave's idea of infinity. double octave_Inf; @@ -53,6 +54,21 @@ // Octave's idea of not a number. double octave_NaN; +// Octave's idea of a missing value. +double octave_NA; + +static int hw; +static int lw; + +typedef union +{ + double value; + unsigned int word[2]; +} ieee_double; + +#define NA_HW 0x7ff00000 +#define NA_LW 1954 + void octave_ieee_init (void) { @@ -90,6 +106,27 @@ octave_NaN = octave_Inf / octave_Inf; #endif + // This is patterned after code in R. + + oct_mach_info::float_format ff = oct_mach_info::native_float_format (); + + if (ff == oct_mach_info::ieee_big_endian) + { + hw = 0; + lw = 1; + } + else + { + hw = 1; + lw = 0; + } + + ieee_double t; + t.word[hw] = NA_HW; + t.word[lw] = NA_LW; + + octave_NA = t.value; + #endif } @@ -109,6 +146,20 @@ #endif +extern "C" int +lo_ieee_is_NA (double x) +{ + ieee_double t; + t.value = x; + return (isnan (x) && t.word[lw] == NA_LW) ? 1 : 0; +} + +extern "C" int +lo_ieee_is_NaN_or_NA (double x) +{ + return isnan (x); +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff -r 00d06e24cc89 -r cfb762dc9259 liboctave/lo-ieee.h --- a/liboctave/lo-ieee.h Wed Aug 07 07:11:44 2002 +0000 +++ b/liboctave/lo-ieee.h Fri Aug 09 06:32:16 2002 +0000 @@ -29,8 +29,14 @@ // Octave's idea of not a number. extern double octave_NaN; +// Octave's idea of a missing value. +extern double octave_NA; + extern void octave_ieee_init (void); +extern "C" int lo_ieee_is_NA (double); +extern "C" int lo_ieee_is_NaN_or_NA (double); + #if defined (SCO) extern "C" int isnan (double); extern "C" int isinf (double); diff -r 00d06e24cc89 -r cfb762dc9259 liboctave/lo-mappers.cc --- a/liboctave/lo-mappers.cc Wed Aug 07 07:11:44 2002 +0000 +++ b/liboctave/lo-mappers.cc Fri Aug 09 06:32:16 2002 +0000 @@ -143,7 +143,7 @@ xisnan (double x) { #if defined (HAVE_ISNAN) - return isnan (x) != 0; + return isnan (x) ? ! lo_ieee_is_NA (x) : false; #else return false; #endif @@ -153,11 +153,11 @@ xfinite (double x) { #if defined (HAVE_FINITE) - return finite (x) != 0; -#elif defined (HAVE_ISINF) && defined (HAVE_ISNAN) - return (! isinf (x) && ! isnan (x)); + return finite (x) != 0 && ! octave_is_NaN_or_NA (x); +#elif defined (HAVE_ISINF) + return (! isinf (x) && ! octave_is_NaN_or_NA (x)); #else - return true; + return ! octave_is_NaN_or_NA (x); #endif } @@ -166,15 +166,29 @@ { #if defined (HAVE_ISINF) return isinf (x); -#elif defined (HAVE_FINITE) && defined (HAVE_ISNAN) - return (! (finite (x) || isnan (x))); +#elif defined (HAVE_FINITE) + return (! (finite (x) || octave_is_NaN_or_NA (x))); #else return false; #endif } +bool +octave_is_NA (double x) +{ + return lo_ieee_is_NA (x); +} + +bool +octave_is_NaN_or_NA (double x) +{ + return lo_ieee_is_NaN_or_NA (x); +} + // (double, double) -> double mappers. +// XXX FIXME XXX -- need to handle NA too? + double xmin (double x, double y) { @@ -288,17 +302,17 @@ bool xisnan (const Complex& x) { -#if defined (HAVE_ISNAN) - return (isnan (real (x)) || isnan (imag (x))); -#else - return false; -#endif + return (xisnan (real (x)) || xisnan (imag (x))); } bool xfinite (const Complex& x) { - return (xfinite (real (x)) && xfinite (imag (x))); + double rx = real (x); + double ix = imag (x); + + return (xfinite (rx) && ! octave_is_NaN_or_NA (rx) + && xfinite (ix) && ! octave_is_NaN_or_NA (ix)); } bool @@ -307,8 +321,22 @@ return (xisinf (real (x)) || xisinf (imag (x))); } +bool +octave_is_NA (const Complex& x) +{ + return (octave_is_NA (real (x)) || octave_is_NA (imag (x))); +} + +bool +octave_is_NaN_or_NA (const Complex& x) +{ + return (octave_is_NaN_or_NA (real (x)) || octave_is_NaN_or_NA (imag (x))); +} + // (complex, complex) -> complex mappers. +// XXX FIXME XXX -- need to handle NA too? + Complex xmin (const Complex& x, const Complex& y) { diff -r 00d06e24cc89 -r cfb762dc9259 liboctave/lo-mappers.h --- a/liboctave/lo-mappers.h Wed Aug 07 07:11:44 2002 +0000 +++ b/liboctave/lo-mappers.h Fri Aug 09 06:32:16 2002 +0000 @@ -39,6 +39,9 @@ extern bool xfinite (double x); extern bool xisinf (double x); +extern bool octave_is_NA (double x); +extern bool octave_is_NaN_or_NA (double x); + extern double xmin (double x, double y); extern double xmax (double x, double y); diff -r 00d06e24cc89 -r cfb762dc9259 src/ChangeLog --- a/src/ChangeLog Wed Aug 07 07:11:44 2002 +0000 +++ b/src/ChangeLog Fri Aug 09 06:32:16 2002 +0000 @@ -1,3 +1,18 @@ +2002-08-09 John W. Eaton + + * parse.y (switch_case): Make list of command optional. + +2002-08-08 John W. Eaton + + * pr-output.cc (pr_max_internal): Use octave_is_NaN_or_NA instead + of xisnan. + (pr_min_internal): Likewise. + (output_max_field_width): Likewise. + (output_precision): Likewise. + (pr_any_float): Handle NA. + * mappers.cc (Fisna, F_is_nan_or_na): New functions. + * data.cc (symbols_of_data): New constant, NA. + 2002-08-07 John W. Eaton * pt-binop.h (tree_binary_expression::is_binary_expression): diff -r 00d06e24cc89 -r cfb762dc9259 src/data.cc --- a/src/data.cc Wed Aug 07 07:11:44 2002 +0000 +++ b/src/data.cc Fri Aug 09 06:32:16 2002 +0000 @@ -1193,6 +1193,12 @@ DEFCONST (J, Complex (0.0, 1.0), IMAGINARY_DOC_STRING); + DEFCONST (NA, octave_NA, + "-*- texinfo -*-\n\ +@defvr {Built-in Variable} NA\n\ +Missing value.\n\ +@end defvr"); + DEFCONST (NaN, octave_NaN, NAN_DOC_STRING); diff -r 00d06e24cc89 -r cfb762dc9259 src/mappers.cc --- a/src/mappers.cc Wed Aug 07 07:11:44 2002 +0000 +++ b/src/mappers.cc Fri Aug 09 06:32:16 2002 +0000 @@ -429,8 +429,8 @@ \n\ @example\n\ @group\n\ -isinf ([13, Inf, NaN])\n\ - @result{} [ 0, 1, 0 ]\n\ +isinf ([13, Inf, NA, NaN])\n\ + @result{} [ 0, 1, 0, 0 ]\n\ @end group\n\ @end example\n\ @end deftypefn"); @@ -447,6 +447,35 @@ Return 1 for characters that are lower case letters.\n\ @end deftypefn"); + DEFUN_MAPPER (isna, 0, octave_is_NA, octave_is_NA, 0, 0, 0, 0.0, 0.0, 0, + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} isna (@var{x})\n\ +Return 1 for elements of @var{x} that are NA (missing) values and zero\n\ +otherwise. For example,\n\ +\n\ +@example\n\ +@group\n\ +is_NA ([13, Inf, NA, NaN])\n\ + @result{} [ 0, 0, 1, 0 ]\n\ +@end group\n\ +@end example\n\ +@end deftypefn"); + + DEFUN_MAPPER (is_nan_or_na, 0, octave_is_NaN_or_NA, + octave_is_NaN_or_NA, 0, 0, 0, 0.0, 0.0, 0, + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} is_nan_or_na (@var{x})\n\ +Return 1 for elements of @var{x} that are NaN or NA (missing) values\n\ +and zero otherwise. For example,\n\ +\n\ +@example\n\ +@group\n\ +is_NAN_or_NA ([13, Inf, NA, NaN])\n\ + @result{} [ 0, 0, 1, 1 ]\n\ +@end group\n\ +@end example\n\ +@end deftypefn"); + DEFUN_MAPPER (isnan, 0, xisnan, xisnan, 0, 0, 0, 0.0, 0.0, 0, "-*- texinfo -*-\n\ @deftypefn {Mapping Function} {} isnan (@var{x})\n\ @@ -455,8 +484,8 @@ \n\ @example\n\ @group\n\ -isnan ([13, Inf, NaN])\n\ - @result{} [ 0, 0, 1 ]\n\ +isnan ([13, Inf, NA, NaN])\n\ + @result{} [ 0, 0, 0, 1 ]\n\ @end group\n\ @end example\n\ @end deftypefn"); diff -r 00d06e24cc89 -r cfb762dc9259 src/parse.y --- a/src/parse.y Wed Aug 07 07:11:44 2002 +0000 +++ b/src/parse.y Fri Aug 09 06:32:16 2002 +0000 @@ -998,7 +998,7 @@ } ; -switch_case : CASE stash_comment opt_sep expression opt_sep list +switch_case : CASE stash_comment opt_sep expression opt_sep opt_list { $$ = make_switch_case ($4, $6, $2); } ; diff -r 00d06e24cc89 -r cfb762dc9259 src/pr-output.cc --- a/src/pr-output.cc Wed Aug 07 07:11:44 2002 +0000 +++ b/src/pr-output.cc Fri Aug 09 06:32:16 2002 +0000 @@ -215,7 +215,7 @@ for (int i = 0; i < nr; i++) { double val = m(i,j); - if (xisinf (val) || xisnan (val)) + if (xisinf (val) || octave_is_NaN_or_NA (val)) continue; if (val > result) @@ -237,7 +237,7 @@ for (int i = 0; i < nr; i++) { double val = m(i,j); - if (xisinf (val) || xisnan (val)) + if (xisinf (val) || octave_is_NaN_or_NA (val)) continue; if (val < result) @@ -1138,6 +1138,13 @@ else os << s; } + else if (octave_is_NA (d)) + { + if (fw > 0) + os << std::setw (fw) << "NA"; + else + os << "NA"; + } else if (xisnan (d)) { if (fw > 0) @@ -2102,7 +2109,7 @@ { double val; if (builtin_real_scalar_variable ("output_max_field_width", val) - && ! xisnan (val)) + && ! octave_is_NaN_or_NA (val)) { int ival = NINT (val); if (ival > 0 && ival == val) @@ -2120,7 +2127,7 @@ { double val; if (builtin_real_scalar_variable ("output_precision", val) - && ! xisnan (val)) + && ! octave_is_NaN_or_NA (val)) { int ival = NINT (val); if (ival >= 0 && ival == val)