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	Wed May 14 18:09:56 2008 +0200
+++ b/liboctave/lo-utils.cc	Sun Apr 27 22:34:17 2008 +0200
@@ -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++ ***