[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commits] r20036 - in /libdfp/trunk: ./ dfp/decimal/ tests/
- To: commits@xxxxxxxxxx
- Subject: [Commits] r20036 - in /libdfp/trunk: ./ dfp/decimal/ tests/
- From: ryanarn@xxxxxxxxxx
- Date: Tue, 07 Aug 2012 23:20:58 -0000
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