libstdc++/5045 (take4) (was: Re: [PATCH] Fix libstdc++/5045 (take3))
Paolo Carlini
pcarlini@unitus.it
Tue Dec 11 11:38:00 GMT 2001
Ross Smith wrote:
> Philip Martin wrote:
> >
> > Paolo Carlini <pcarlini@unitus.it> writes:
> >
> > > Well, that is for <bool>, right? In that case I think std_limits.h (please check!) ends up setting
> > > 1 digit anyway.
> >
> > Of course, I see now, it's the only case where digits10 is not just
> > the number of digits that can be represented without change, it's also
> > the maximum number of digits.
>
> For bool, digits10 should be 0, shouldn't it?
Hi Ross!
I think you are correct, in fact, and this time both me and Philip are wrong (but Philip "felt" that
something was wrong with bool ;-) : on a bool only 0 digit base-10 numbers can be represented *without
change*.
This update affects the current "best" patch in 3 different places:
1- num_get::do_get(bool)
2- std_limits.h
3- The testsuite entry
3- ... the ChangeLog, of course.
Cheers,
Paolo.
///////////////
I'm attaching below for our convenience the current patch:
2001-12-11 Philip Martin <philip@codematters.co.uk>
Ross Smith <r-smith@ihug.co.nz>
Paolo Carlini <pcarlini@unitus.it>
libstdc++/5045
* include/bits/std_limits.h (defines, numeric_limits<bool>::digits10):
Fix digits10 values for integral types.
* include/bits/locale_facets.tcc (num_get::do_get for integral types):
Tweak _M_extract_int call.
* testsuite/27_io/istream_extractor_arith.cc (test13, test12_aux): Tweak
overflowing number of digits.
* testsuite/18_support/numeric_limits.cc (test03): New testcase.
diff -urN libstdc++-v3-vanilla/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
--- libstdc++-v3-vanilla/include/bits/locale_facets.tcc Mon Dec 10 14:37:55 2001
+++ libstdc++-v3/include/bits/locale_facets.tcc Tue Dec 11 20:30:19 2001
@@ -390,8 +390,12 @@
// integral types
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<bool>::digits10, __base);
+ // According to 18.2.1.2.9, digits10 is "Number of base 10 digits
+ // that can be represented without change" so we have to add 1 to it
+ // in order to obtain the max number of digits. The same for the
+ // other do_get for integral types below.
+ _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<bool>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -456,7 +460,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<long>::digits10, __base);
+ numeric_limits<long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -482,7 +486,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned short>::digits10, __base);
+ numeric_limits<unsigned short>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -509,7 +513,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned int>::digits10, __base);
+ numeric_limits<unsigned int>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -536,7 +540,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long>::digits10, __base);
+ numeric_limits<unsigned long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -563,7 +567,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<long long>::digits10, __base);
+ numeric_limits<long long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -589,7 +593,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long long>::digits10, __base);
+ numeric_limits<unsigned long long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -718,7 +722,7 @@
char __xtrc[32];
int __base;
_M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long>::digits10, __base);
+ numeric_limits<unsigned long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
diff -urN libstdc++-v3-vanilla/include/bits/std_limits.h libstdc++-v3/include/bits/std_limits.h
--- libstdc++-v3-vanilla/include/bits/std_limits.h Mon Dec 10 21:33:27 2001
+++ libstdc++-v3/include/bits/std_limits.h Tue Dec 11 20:27:48 2001
@@ -144,31 +144,31 @@
#define __glibcpp_s8_max 127
#define __glibcpp_s8_min (-__glibcpp_s8_max - 1)
#define __glibcpp_s8_digits 7
-#define __glibcpp_s8_digits10 3
+#define __glibcpp_s8_digits10 2
#define __glibcpp_u8_min 0U
#define __glibcpp_u8_max (__glibcpp_s8_max * 2 + 1)
#define __glibcpp_u8_digits 8
-#define __glibcpp_u8_digits10 3
+#define __glibcpp_u8_digits10 2
#define __glibcpp_s16_max 32767
#define __glibcpp_s16_min (-__glibcpp_s16_max - 1)
#define __glibcpp_s16_digits 15
-#define __glibcpp_s16_digits10 5
+#define __glibcpp_s16_digits10 4
#define __glibcpp_u16_min 0U
#define __glibcpp_u16_max (__glibcpp_s16_max * 2 + 1)
#define __glibcpp_u16_digits 16
-#define __glibcpp_u16_digits10 5
+#define __glibcpp_u16_digits10 4
#define __glibcpp_s32_max 2147483647L
#define __glibcpp_s32_min (-__glibcpp_s32_max - 1)
#define __glibcpp_s32_digits 31
-#define __glibcpp_s32_digits10 10
+#define __glibcpp_s32_digits10 9
#define __glibcpp_u32_min 0UL
#define __glibcpp_u32_max (__glibcpp_s32_max * 2U + 1)
#define __glibcpp_u32_digits 32
-#define __glibcpp_u32_digits10 10
+#define __glibcpp_u32_digits10 9
#define __glibcpp_s64_max 9223372036854775807LL
#define __glibcpp_s64_min (-__glibcpp_s64_max - 1)
#define __glibcpp_s64_digits 63
-#define __glibcpp_s64_digits10 19
+#define __glibcpp_s64_digits10 18
#define __glibcpp_u64_min 0ULL
#define __glibcpp_u64_max (__glibcpp_s64_max * 2ULL + 1)
#define __glibcpp_u64_digits 64
@@ -1033,7 +1033,7 @@
{ return true; }
static const int digits = __glibcpp_bool_digits;
- static const int digits10 = 1;
+ static const int digits10 = 0;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
diff -urN libstdc++-v3-vanilla/testsuite/18_support/numeric_limits.cc
libstdc++-v3/testsuite/18_support/numeric_limits.cc
--- libstdc++-v3-vanilla/testsuite/18_support/numeric_limits.cc Sat Dec 8 01:25:59 2001
+++ libstdc++-v3/testsuite/18_support/numeric_limits.cc Tue Dec 11 20:31:45 2001
@@ -155,10 +155,33 @@
const bool* pb1 = &b_nl_type::traps;
}
+// libstdc++/5045
+bool test03()
+{
+ bool test = true;
+
+ VERIFY( std::numeric_limits<bool>::digits10 == 0 );
+ VERIFY( __glibcpp_s8_digits10 == 2 );
+ VERIFY( __glibcpp_u8_digits10 == 2 );
+ VERIFY( __glibcpp_s16_digits10 == 4 );
+ VERIFY( __glibcpp_u16_digits10 == 4 );
+ VERIFY( __glibcpp_s32_digits10 == 9 );
+ VERIFY( __glibcpp_u32_digits10 == 9 );
+ VERIFY( __glibcpp_s64_digits10 == 18 );
+ VERIFY( __glibcpp_u64_digits10 == 19 );
+
+#ifdef DEBUG_ASSERT
+ assert(test);
+#endif
+
+ return test;
+}
+
int main()
{
test01();
test02();
+ test03();
test_extrema<char>();
test_extrema<signed char>();
diff -urN libstdc++-v3-vanilla/testsuite/27_io/istream_extractor_arith.cc
libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc
--- libstdc++-v3-vanilla/testsuite/27_io/istream_extractor_arith.cc Mon Dec 10 14:37:55 2001
+++ libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc Mon Dec 10 22:06:07 2001
@@ -523,7 +523,7 @@
int digits_overflow;
if (integer_type)
// This many digits will overflow integer types in base 10.
- digits_overflow = std::numeric_limits<T>::digits10 + 1;
+ digits_overflow = std::numeric_limits<T>::digits10 + 2;
else
// This might do it, unsure.
digits_overflow = std::numeric_limits<T>::max_exponent10 + 1;
@@ -573,7 +573,7 @@
// 2
// quick test for failbit on maximum length extraction.
int i;
- int max_digits = numeric_limits<int>::digits10;
+ int max_digits = numeric_limits<int>::digits10 + 1;
string digits;
for (int j = 0; j < max_digits; ++j)
digits += '1';
More information about the Libstdc++
mailing list