Mercurial > hg > octave-terminal
changeset 10357:7658cd4bdcf2
handle Infs and NaNs in str2double
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 25 Feb 2010 11:11:45 +0100 |
parents | 1d7930b77ab9 |
children | 72fab01e5d68 |
files | src/ChangeLog src/DLD-FUNCTIONS/str2double.cc |
diffstat | 2 files changed, 58 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2010-02-25 Jaroslav Hajek <highegg@gmail.com> + + * DLD-FUNCTIONS/str2double.cc (single_number): New helper func. + (extract_number): Call it instead of >> to get Inf's and NaN's + correctly. + 2010-02-25 Jaroslav Hajek <highegg@gmail.com> * DLD-FUNCTIONS/str2double.cc: New source.
--- a/src/DLD-FUNCTIONS/str2double.cc +++ b/src/DLD-FUNCTIONS/str2double.cc @@ -40,13 +40,47 @@ static inline bool is_imag_unit (int c) -{ return c == 'i' || c == 'j' || c == 'I' || c == 'J'; } +{ return c == 'i' || c == 'j'; } + +static std::istringstream& +single_num (std::istringstream& is, double& num) +{ + char c = is.peek (); + if (c == 'I') + { + // It's infinity. + is.get (); + char c1 = is.get (), c2 = is.get (); + if (c1 == 'n' && c2 == 'f') + { + num = octave_Inf; + is.peek (); // Sets eof bit. + } + else + is.setstate (std::ios::failbit); // indicate that read has failed. + } + else if (c == 'N') + { + // It's NaN. + is.get (); + char c1 = is.get (), 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; + + return is; +} static std::istringstream& extract_num (std::istringstream& is, double& num, bool& imag, bool& have_sign) { - if (is.eof ()) - return is; have_sign = imag = false; char c = is.peek (); @@ -63,21 +97,22 @@ if (is_imag_unit (c)) { - is.get (); + c = is.get (); // It's i*num or just i. imag = true; - if (is.peek () == '*') + char cn = is.peek (); + if (cn == '*') { // Multiplier follows, we extract it as a number. is.get (); - is >> num; + single_num (is, num); } else num = 1.0; } else { - is >> num; + single_num (is, num); if (is.good ()) { c = is.peek (); @@ -115,7 +150,9 @@ double num; bool i1, i2, s1, s2; - if (! extract_num (is, num, i1, s1)) + if (is.eof ()) + val = octave_NaN; + else if (! extract_num (is, num, i1, s1)) val = octave_NaN; else { @@ -208,5 +245,12 @@ %!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 ("NaN"), NaN) +%!assert (str2double ("Inf"), Inf) +%!assert (str2double ("-Inf"), -Inf) +%!assert (str2double ("i*Inf"), 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)) */