[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commits] r20036 - in /libdfp/trunk: ./ dfp/decimal/ tests/



Author: ryanarn
Date: Tue Aug  7 23:20:58 2012
New Revision: 20036

Log:
2012-08-07  Ryan S. Arnold  <rsa@xxxxxxxxxxxxxxxxxx>

	* tests/test-printf.c: Add missing 'D' to a/A conv tests.
	* tests/scaffold.c: Correct comments for _OSC and added a/A support.
	* tests/test-ostream.cpp: Modified expectations such that a/A ignores
	precision and always uses the num of significant digits in the
	mantissa when output.
	* tests/test-ostream-g-spec.cpp: Removed unnecessary define that used
	to be used to get g/G support.
	* dfp/decimal/decimal (FIND_DEC_MANT_DIG): Remove ".*" from default
	string string.
	(LIBDFP_META): Make g/G spec default. Enable a/A spec by checking
	flags for ios::fixed | ios::scientific. Condense uppercase/lowercase
	check. Don't call printf with a precision specifier if a/A is the
	desires spec conv.



Modified:
    libdfp/trunk/ChangeLog
    libdfp/trunk/dfp/decimal/decimal
    libdfp/trunk/tests/scaffold.c
    libdfp/trunk/tests/test-ostream-g-spec.cpp
    libdfp/trunk/tests/test-ostream.cpp
    libdfp/trunk/tests/test-printf.c

Modified: libdfp/trunk/ChangeLog
==============================================================================
--- libdfp/trunk/ChangeLog (original)
+++ libdfp/trunk/ChangeLog Tue Aug  7 23:20:58 2012
@@ -1,3 +1,19 @@
+2012-08-07  Ryan S. Arnold  <rsa@xxxxxxxxxxxxxxxxxx>
+
+	* tests/test-printf.c: Add missing 'D' to a/A conv tests.
+	* tests/scaffold.c: Correct comments for _OSC and added a/A support.
+	* tests/test-ostream.cpp: Modified expectations such that a/A ignores
+	precision and always uses the num of significant digits in the
+	mantissa when output.
+	* tests/test-ostream-g-spec.cpp: Removed unnecessary define that used
+	to be used to get g/G support.
+	* dfp/decimal/decimal (FIND_DEC_MANT_DIG): Remove ".*" from default
+	string string.
+	(LIBDFP_META): Make g/G spec default. Enable a/A spec by checking
+	flags for ios::fixed | ios::scientific. Condense uppercase/lowercase
+	check. Don't call printf with a precision specifier if a/A is the
+	desires spec conv.
+
 2012-07-27  Ryan S. Arnold  <rsa@xxxxxxxxxxxxxxxxxx>
 
 	* tests/test-negate.c: New testcase.

Modified: libdfp/trunk/dfp/decimal/decimal
==============================================================================
--- libdfp/trunk/dfp/decimal/decimal (original)
+++ libdfp/trunk/dfp/decimal/decimal Tue Aug  7 23:20:58 2012
@@ -65,6 +65,7 @@
 struct FIND_DEC_MANT_DIG
 {
   enum {RESULT = 0};
+
   static inline std::string get_fmt(char conv)
   {
      std::string spec = "";
@@ -78,7 +79,7 @@
   enum {RESULT = (__DEC32_MANT_DIG__) };
   static inline std::string get_fmt(char conv)
   {
-     std::string spec = "%.*H";
+     std::string spec = "H";
      return spec.append(1,conv);
   }
 };
@@ -88,7 +89,7 @@
   enum {RESULT = (__DEC64_MANT_DIG__) };
   static inline std::string get_fmt(char conv)
   {
-     std::string spec = "%.*D";
+     std::string spec = "D";
      return spec.append(1,conv);
   }
 
@@ -99,7 +100,7 @@
   enum {RESULT = (__DEC128_MANT_DIG__) };
   static inline std::string get_fmt(char conv)
   {
-     std::string spec = "%.*DD";
+     std::string spec = "DD";
      return spec.append(1,conv);
   }
 };
@@ -128,64 +129,42 @@
       ios_base::fmtflags flags = os.flags();
       unsigned int precision = os.precision();
 
+      /* Anything over DEC_MANT_DIG can't be represented anyway.  */
       if (precision > DEC_MANT_DIG)
         precision = DEC_MANT_DIG;
 
-      /* ISO/IEC TR 24733 (DFP C++ Technical Report) doesn't have a
-       * specific ios:: flag that matches the 'a/A' conversion specifier
-       * defined in ISO/IEC TR 24732 (DFP C Technical Report).  Nor does it
-       * specify a default.  It only identifies ios::fixed and
-       * ios::scientific.  There is no default ios_base::fmtflags set if
-       * the user has not specified one or the other.  Presumably the 'g/G'
-       * specifier would be chosen as the default since this implicitly
-       * chooses f/F or e/E based on the number encountered.  */
-
-      /* This ostream implementation prefers the behavior of the DFP C TR
-       * 'a/A' conversion specifier as the default over 'g/G'.  The 'a/A'
-       * conversion specifier is preferred because 'a/A' includes the
-       * number of digits left of the decimal point in the specified
-       * precision.  This is important because a decimal mantissa has a
-       * fixed number of digits and there is no forced (approximate)
-       * rounding, like in binary floating point.  */
-
-      /* This implementation allows one of three approaches.  It can
-       * either use 'a/A' by default or it can allow the user to select
-       * 'f/F' (with ios::fixed) or 'e/E' (with ios::scientific).
-
-      /* IF the user wants 'g/G' as the default he should compile with
-       * #define _LIBDFP_G_CONV_SPEC. */
-
-#ifdef _LIBDFP_G_CONV_SPEC
       char conv = 'g';
-#else
-      char conv = 'a';
-#endif
-
-      if (flags & ios::fixed)
+
+      std::string fmtstr = "%";
+
+      /* A strict reading of the draft DFP C++ spec indicates that a/A conv
+         specifier can't be accompanied by a precision specifier.  */
+
+      if (flags & ios::fixed && flags & ios::scientific)
+	  conv = flags & ios::uppercase ? 'A' : 'a';
+      else
         {
-          /* Only used for "NAN" and "INF" rather than "nan" and "inf" for
-           * "%.*Df".  */
-          if (flags & ios::uppercase)
-            conv = 'F';
-          else
-            conv = 'f';
-        }
-      else if (flags & ios::scientific)
-       {
-          if (flags & ios::uppercase)
-            conv = 'E';
-          else
-            conv = 'e';
-        }
-      else if (flags & ios::uppercase)
-#ifdef _LIBDFP_G_CONV_SPEC
-        conv = 'G';
-#else
-        conv = 'A';
-#endif
-
-      std::string fmtstr = FIND_DEC_MANT_DIG<(sizeof(decimal_type))>::get_fmt(conv);
-      sprintf (strbuf, fmtstr.c_str(), precision, d.__getval());
+	  if (flags & ios::fixed)
+	      /* Only used for "NAN" and "INF" rather than "nan" and "inf" for
+	       * "%.*Df".  */
+	      conv = flags & ios::uppercase ? 'F' : 'f';
+	  else if (flags & ios::scientific)
+	      conv = flags & ios::uppercase ? 'E' : 'e';
+	  else if (flags & ios::uppercase)
+	      conv = 'G';
+	  fmtstr.append(".*");
+	}
+
+      /* Get the conv spec and length modifier based on size of the type.  */
+      fmtstr.append(FIND_DEC_MANT_DIG<(sizeof(decimal_type))>::get_fmt(conv));
+
+      /* Per the confusing reading of the draft DFP C++ Specification, a/A type
+         are never passed with an accompanying precision.  This causes the
+	 implicit precision in the type to be used for printing.  */
+      if (flags & ios::fixed && flags & ios::scientific)
+        sprintf (strbuf, fmtstr.c_str(), d.__getval());
+      else
+        sprintf (strbuf, fmtstr.c_str(), precision, d.__getval());
       os << strbuf;
       return os;
     }

Modified: libdfp/trunk/tests/scaffold.c
==============================================================================
--- libdfp/trunk/tests/scaffold.c (original)
+++ libdfp/trunk/tests/scaffold.c Tue Aug  7 23:20:58 2012
@@ -69,9 +69,9 @@
     flags |= ios::fixed;				\
   else if (spec == 'e')					\
     flags |= ios::scientific;				\
-  /* else if (spec == 'a') this is the default.  */	\
-  /* or else if (spec == 'g') this is the default  */	\
-  /* if _LIBDFP_G_CONV_SPEC is defined.  */		\
+  else if (spec == 'a')					\
+    flags |= (ios::scientific | ios::fixed);		\
+  /* else if (spec == 'g') this is the default.  */	\
   s.flags(flags);					\
   s << y;						\
   _SC_P(f,l,x,s.str().c_str());				\
@@ -82,16 +82,19 @@
  * Macro used to compare an ostream (operator<<) invocation with an expected
  * result.
  *
- * X: Expected String
- * Y: decimal[32|64|128] value
+ * X: decimal[32|64|128] value
+ * Y: Expected String
  * precision: Desired precision of output (can't exceed
  *            __DEC[32|64|128]_MANT_DIG__.  Equivalent to setprecision(x).
  * upper: 'l' is default.  'u' means uppercase; equivalent to ios::uppercase.
- * spec: 'a' is default.  'e' equivalent to ios::scientific, 'f' equivalent to
- *        ios::fixed.
+ * spec: 'g' is default.  'e' equivalent to ios::scientific, 'f' equivalent to
+ *        ios::fixed, 'a' is equivalent to ios::scientific | ios::fixed.
  *
  * e.g.
- *   _OSC("-0.009999",-9.999E-3DD, -1, 'l', 'f');
+ *   _OSC(4.000000000000000e+384DD, "4.000000000000000e384", -1, 'l', 'a');
+ *   _OSC(4.000000000000000e+384DD, "4.000000000000000e384", -1, 'l', 'g');
+ *   _OSC(4.000000000000000e+384DD, "4.00000e384", -1, 'l', 'f');
+ *   _OSC(4.000000000000000e+384DD, "4.00000e384", -1, 'l', 'f');
  *
  * Equivalent to the following example:
  *

Modified: libdfp/trunk/tests/test-ostream-g-spec.cpp
==============================================================================
--- libdfp/trunk/tests/test-ostream-g-spec.cpp (original)
+++ libdfp/trunk/tests/test-ostream-g-spec.cpp Tue Aug  7 23:20:58 2012
@@ -30,10 +30,6 @@
  * definitions.  */
 #include <float.h>
 
-/* This testcase sets _LIBDFP_G_CONV_SPEC which causes decimal/decimal's
- * operator<< to default to the equivalent of an printf g/G spec conv rather
- * than the DFP SPEC printf a/A spec conv.  */
-#define _LIBDFP_G_CONV_SPEC
 #include <decimal/decimal>
 
 #include <iomanip>
@@ -55,8 +51,11 @@
   const char *expect;
   int precision; /* -1 means unspecified.  */
   char upper; /* l or u */
-  char spec; /* a, e, f */
+  char spec; /* a, e, f, g */
 } d32_type;
+
+/* The g/G conv spec used to be provided separate from the others
+   so there was a separate test program.  */
 
 d32_type ostream_d32s[] =
 {

Modified: libdfp/trunk/tests/test-ostream.cpp
==============================================================================
--- libdfp/trunk/tests/test-ostream.cpp (original)
+++ libdfp/trunk/tests/test-ostream.cpp Tue Aug  7 23:20:58 2012
@@ -85,6 +85,12 @@
   {__LINE__, (0.0DD * __builtin_infd64()), "nan", -1, 'l', 'a' },
   {__LINE__, -(0.0DD * __builtin_infd64()), "-NAN", -1, 'u', 'a' },
   {__LINE__, -(0.0DD * __builtin_infd64()), "-nan", -1, 'l', 'a' },
+  /* Due to the lack of direction in the C++ DFP TR there is no indication
+     that a/A conv specifiers should accept precision.  */
+  {__LINE__, 4.000000000000000e+384DD, "4.000000000000000e+384", -1, 'l', 'a' },
+  {__LINE__, 4.000000000000000e+384DD, "4.000000000000000e+384", 7, 'l', 'a' },
+  {__LINE__, 4.000000000000000e+384DD, "4.000000000000000e+384", 6, 'l', 'a' },
+  {__LINE__, 4.000000000000000e+384DD, "4.000000000000000e+384", 19, 'l', 'a' },
   {0,0,0,0,0,0}
 };
 
@@ -99,8 +105,8 @@
 
 d128_type ostream_d128s[] =
 {
-  {__LINE__, -1234.56789123456789123455678DL, "-1234.57", -1, 'l', 'a' },
-  {__LINE__, -1234.56789123456789123455678DL, "-1234.5679", 8, 'l', 'a' },
+  {__LINE__, -1234.56789123456789123455678DL, "-1234.56789123456789123455678", -1, 'l', 'a' },
+  {__LINE__, -1234.56789123456789123455678DL, "-1234.56789123456789123455678", 8, 'l', 'a' },
   {__LINE__, -12345678912345678.9123455678DL, "-12345678912345678.9123455678", 10, 'u', 'f' },
   {__LINE__, (0.0DL * __builtin_infd128()), "NAN", -1, 'u', 'a' },
   {__LINE__, (0.0DL * __builtin_infd128()), "nan", -1, 'l', 'a' },

Modified: libdfp/trunk/tests/test-printf.c
==============================================================================
--- libdfp/trunk/tests/test-printf.c (original)
+++ libdfp/trunk/tests/test-printf.c Tue Aug  7 23:20:58 2012
@@ -491,6 +491,10 @@
   {__LINE__, 6543.00DD, " 6543.00", "%8Da"},
 
   {__LINE__, __DEC64_MAX__, "9.999999999999999e+384", "%.17Dg" },
+  {__LINE__, __DEC64_MAX__, "9.999999999999999e+384", "%Da" },
+  {__LINE__, __DEC64_MAX__, "1.000000e+385", "%De" },
+  {__LINE__, __DEC64_MAX__, "9.999999999999999e+384", "%.16Da" },
+  {__LINE__, __DEC64_MAX__, "1.00e+385", "%.3Da" },
   {__LINE__, 9.999999999999999E16DD, "9.999999999999999e+16", "%.16Dg" },
   {__LINE__, 9.999999999999999E23DD, "9.999999999999999e+23", "%.16Dg" },
   {__LINE__, 9.999999999999999E300DD, "9.999999999999999e+300", "%.16Dg" },

_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits