Mercurial > hg > octave-lyh
diff liboctave/lo-utils.cc @ 7789:82be108cc558
First attempt at single precision tyeps
* * *
corrections to qrupdate single precision routines
* * *
prefer demotion to single over promotion to double
* * *
Add single precision support to log2 function
* * *
Trivial PROJECT file update
* * *
Cache optimized hermitian/transpose methods
* * *
Add tests for tranpose/hermitian and ChangeLog entry for new transpose code
author | David Bateman <dbateman@free.fr> |
---|---|
date | Sun, 27 Apr 2008 22:34:17 +0200 |
parents | 845ca0affec0 |
children | eb63fbe60fab |
line wrap: on
line diff
--- a/liboctave/lo-utils.cc +++ b/liboctave/lo-utils.cc @@ -62,6 +62,17 @@ return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5)); } +octave_idx_type +NINTbig (float x) +{ + if (x > std::numeric_limits<octave_idx_type>::max ()) + return std::numeric_limits<octave_idx_type>::max (); + else if (x < std::numeric_limits<octave_idx_type>::min ()) + return std::numeric_limits<octave_idx_type>::min (); + else + return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + int NINT (double x) { @@ -73,6 +84,17 @@ return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5)); } +int +NINT (float x) +{ + if (x > std::numeric_limits<int>::max ()) + return std::numeric_limits<int>::max (); + else if (x < std::numeric_limits<int>::min ()) + return std::numeric_limits<int>::min (); + else + return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5)); +} + double D_NINT (double x) { @@ -82,6 +104,15 @@ return floor (x + 0.5); } +float +F_NINT (float x) +{ + if (xisinf (x) || xisnan (x)) + return x; + else + return floor (x + 0.5); +} + // Save a string. char * @@ -379,6 +410,196 @@ os << ")"; } + + + + + + + + + + + + + + + + + + + + + +static inline float +read_float_inf_nan_na (std::istream& is, char c, char sign = '+') +{ + float d = 0.0; + + switch (c) + { + case 'i': case 'I': + { + c = is.get (); + if (c == 'n' || c == 'N') + { + c = is.get (); + if (c == 'f' || c == 'F') + d = sign == '-' ? -octave_Inf : octave_Inf; + else + is.putback (c); + } + else + is.putback (c); + } + break; + + case 'n': case 'N': + { + c = is.get (); + if (c == 'a' || c == 'A') + { + c = is.get (); + if (c == 'n' || c == 'N') + d = octave_NaN; + else + { + is.putback (c); + d = octave_NA; + } + } + else + is.putback (c); + } + break; + + default: + abort (); + } + + return d; +} + +float +octave_read_float (std::istream& is) +{ + float d = 0.0; + + char c1 = ' '; + + while (isspace (c1)) + c1 = is.get (); + + switch (c1) + { + case '-': + { + char c2 = 0; + c2 = is.get (); + if (c2 == 'i' || c2 == 'I') + d = read_float_inf_nan_na (is, c2, c1); + else + { + is.putback (c2); + is.putback (c1); + is >> d; + } + } + break; + + case '+': + { + char c2 = 0; + c2 = is.get (); + if (c2 == 'i' || c2 == 'I') + d = read_float_inf_nan_na (is, c2, c1); + else + { + is.putback (c2); + is.putback (c1); + is >> d; + } + } + break; + + case 'i': case 'I': + case 'n': case 'N': + d = read_float_inf_nan_na (is, c1); + break; + + default: + is.putback (c1); + is >> d; + } + + return d; +} + +FloatComplex +octave_read_float_complex (std::istream& is) +{ + float re = 0.0, im = 0.0; + + FloatComplex cx = 0.0; + + char ch = ' '; + + while (isspace (ch)) + ch = is.get (); + + if (ch == '(') + { + re = octave_read_float (is); + ch = is.get (); + + if (ch == ',') + { + im = octave_read_float (is); + ch = is.get (); + + if (ch == ')') + cx = FloatComplex (re, im); + else + is.setstate (std::ios::failbit); + } + else if (ch == ')') + cx = re; + else + is.setstate (std::ios::failbit); + } + else + { + is.putback (ch); + cx = octave_read_float (is); + } + + return cx; + +} + +void +octave_write_float (std::ostream& os, float d) +{ + if (lo_ieee_is_NA (d)) + os << "NA"; + else if (lo_ieee_isnan (d)) + os << "NaN"; + else if (lo_ieee_isinf (d)) + os << (d < 0 ? "-Inf" : "Inf"); + else + os << d; +} + +void +octave_write_float_complex (std::ostream& os, const FloatComplex& c) +{ + os << "("; + octave_write_float (os, real (c)); + os << ","; + octave_write_float (os, imag (c)); + os << ")"; +} + /* ;;; Local Variables: *** ;;; mode: C++ ***