changeset 11414:5e6ef42a2445

Overhaul str2double function fixing bug and docstring and adding 'NA' processing.
author Rik <octave@nomad.inbox5.com>
date Sat, 25 Dec 2010 07:47:50 -0800
parents ae0deb52af27
children e7ed20f87e82
files src/ChangeLog src/DLD-FUNCTIONS/str2double.cc
diffstat 2 files changed, 56 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2010-12-25  Rik  <octave@nomad.inbox5.com>
+
+	* DLD-FUNCTIONS/str2double.cc: Fix bug in converting "numberi" strings
+	such as "2i".  Add ability to process special value "NA".  Rewrite 
+	docstring.
+
 2010-12-25  Rik  <octave@nomad.inbox5.com>
 
 	* input.cc (PS1): Correct use of xref macro to remove Tex warning.
--- a/src/DLD-FUNCTIONS/str2double.cc
+++ b/src/DLD-FUNCTIONS/str2double.cc
@@ -61,16 +61,25 @@
     }
   else if (c == 'N')
     {
-      // It's NaN.
+      // It's NA or NaN
       is.get ();
-      char c1 = is.get (), c2 = is.get ();
-      if (c1 == 'a' && c2 == 'N')
+      char c1 = is.get ();
+      if (c1 == 'A')
         {
-          num = octave_NaN;
+          num = octave_NA;
           is.peek (); // Sets eof bit.
         }
-      else
-        is.setstate (std::ios::failbit); // indicate that read has failed.
+      else 
+        {
+          char c2 = is.get ();
+          if (c1 == 'a' && c2 == 'N')
+            {
+              num = octave_NaN;
+              is.peek (); // Sets eof bit.
+            }
+          else
+            is.setstate (std::ios::failbit); // indicate that read has failed.
+        }
     }
   else
     is >> num;
@@ -95,10 +104,10 @@
       have_sign = true;
     }
 
+  // It's i*num or just i.
   if (is_imag_unit (c))
     {
       c = is.get ();
-      // It's i*num or just i.
       imag = true;
       char cn = is.peek ();
       if (cn == '*')
@@ -112,6 +121,7 @@
     }
   else
     {
+      // It's num, num*i, or numi.
       single_num (is, num);
       if (is.good ())
         {
@@ -121,12 +131,19 @@
               is.get ();
               c = is.get ();
               if (is_imag_unit (c))
-                imag = true;
+                {
+                  imag = true;
+                  is.peek ();
+                }
               else
                 is.setstate (std::ios::failbit); // indicate that read has failed.
             }
           else if (is_imag_unit (c))
-            imag = true;
+            {
+              imag = true;
+              is.get ();
+              is.peek ();
+            }
         }
     }
 
@@ -198,8 +215,10 @@
 DEFUN_DLD (str2double, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} str2double (@var{s})\n\
-Converts a string to real or complex number.\n\
-A complex number should be in one of the formats:\n\
+Convert a string to a real or complex number.\n\
+\n\
+The string must be in one of the following formats where\n\
+a and b are real numbers and the complex unit is 'i' or 'j':\n\
 \n\
 @itemize\n\
 @item a + bi\n\
@@ -215,13 +234,19 @@
 @item i*b + a\n\
 @end itemize\n\
 \n\
-It is also possible to use @code{j} instead of @code{i}, or write just\n\
-@code{i} instead of @code{1*i}.\n\
-@code{a} and @code{b} should be real numbers\n\
-in a standard format.\n\
-@var{s} can also be a character matrix, in which case the conversion is\n\
-repeated for each row, or a cell array of strings, in which case each element\n\
-is converted and an array of the same dimensions is returned.\n\
+If present, a and/or b are of the form [+-]d[,.]d[[eE][+-]d] where the\n\
+brackets indicate optional arguments and 'd' indicates zero or more\n\
+digits.  The special input values @code{Inf}, @code{NaN}, and @code{NA} are\n\
+also accepted.\n\
+\n\
+@var{s} may also be a character matrix, in which case the conversion is\n\
+repeated for each row.  Or @var{s} may be a cell array of strings, in which\n\
+case each element is converted and an array of the same dimensions is\n\
+returned.\n\
+\n\
+@code{str2double} can replace @code{str2num}, but avoids the use of\n\
+@code{eval} on unknown data.\n\
+@seealso{str2num}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -261,16 +286,19 @@
 %!assert (str2double ("-.1e-5"), -1e-6)
 %!assert (str2double ("1,222.5"), 1222.5)
 %!assert (str2double ("i"), i)
+%!assert (str2double ("2j"), 2i)
 %!assert (str2double ("2 + j"), 2+j)
 %!assert (str2double ("i*2 + 3"), 3+2i)
 %!assert (str2double (".5*i + 3.5"), 3.5+0.5i)
-%!assert (str2double ("1e-3 + i*.25"), 1e-3 + i*.25)
-%!assert (str2double (["2 + j";"1.25e-3";"-05"]), [2+i; 1.25e-3; -05])
-%!assert (str2double ({"2 + j","1.25e-3","-05"}), [2+i, 1.25e-3, -05])
+%!assert (str2double ("1e-3 + i*.25"), 1e-3 + 0.25i)
+%!assert (str2double (["2 + j";"1.25e-3";"-05"]), [2+i; 1.25e-3; -5])
+%!assert (str2double ({"2 + j","1.25e-3","-05"}), [2+i, 1.25e-3, -5])
+%!assert (str2double ("Hello World"), NaN)
 %!assert (str2double ("NaN"), NaN)
+%!assert (str2double ("NA"), NA)
 %!assert (str2double ("Inf"), Inf)
 %!assert (str2double ("-Inf"), -Inf)
-%!assert (str2double ("i*Inf"), complex (0, Inf))
+%!assert (str2double ("Inf*i"), complex (0, Inf))
 %!assert (str2double ("NaN + Inf*i"), complex (NaN, Inf))
 %!assert (str2double ("Inf - Inf*i"), complex (Inf, -Inf))
 %!assert (str2double ("-i*NaN - Inf"), complex (-Inf, -NaN))