1 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // <charconv> is supported in C++14 as a GNU extension
19 // { dg-do run { target c++14 } }
20 // { dg-add-options ieee }
27 #include <testsuite_hooks.h>
29 // Test std::from_chars floating-point conversions.
31 #if __cpp_lib_to_chars >= 201611L
37 std::from_chars_result res
;
39 for (auto fmt
: { std::chars_format::fixed
, std::chars_format::scientific
,
40 std::chars_format::general
, std::chars_format::hex
})
43 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
44 VERIFY( std::isinf(d
) );
45 VERIFY( res
.ptr
== s
.data() + 3 );
46 VERIFY( res
.ec
== std::errc
{} );
49 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
50 VERIFY( std::isinf(d
) );
52 VERIFY( res
.ptr
== s
.data() + 4 );
53 VERIFY( res
.ec
== std::errc
{} );
55 s
= "InFiNiTy aNd BeYoNd";
56 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
57 VERIFY( std::isinf(d
) );
58 VERIFY( res
.ptr
== s
.data() + 8 );
59 VERIFY( res
.ec
== std::errc
{} );
62 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
63 VERIFY( std::isnan(d
) );
64 VERIFY( res
.ptr
== s
.data() + 3 );
65 VERIFY( res
.ec
== std::errc
{} );
68 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
, fmt
);
69 VERIFY( std::isnan(d
) );
70 VERIFY( res
.ptr
== s
.data() + s
.length() );
71 VERIFY( res
.ec
== std::errc
{} );
80 std::from_chars_result res
;
83 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
85 VERIFY( res
.ptr
== s
.data() + 1 );
86 VERIFY( res
.ec
== std::errc
{} );
89 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
90 std::chars_format::fixed
);
92 VERIFY( res
.ptr
== s
.data() + 1 );
93 VERIFY( res
.ec
== std::errc
{} );
96 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
97 std::chars_format::scientific
);
99 VERIFY( res
.ptr
== s
.data() );
100 VERIFY( res
.ec
== std::errc::invalid_argument
);
103 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
104 std::chars_format::general
);
106 VERIFY( res
.ptr
== s
.data() + 1 );
107 VERIFY( res
.ec
== std::errc
{} );
110 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
111 std::chars_format::hex
);
113 VERIFY( res
.ptr
== s
.data() + 1 );
114 VERIFY( res
.ec
== std::errc
{} );
122 std::from_chars_result res
;
125 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
126 VERIFY( d
== 0.5e+2 );
127 VERIFY( res
.ptr
== s
.data() + s
.length() - 1 - 3 );
128 VERIFY( res
.ec
== std::errc
{} );
130 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
131 std::chars_format::fixed
);
133 VERIFY( res
.ptr
== s
.data() + 3 );
134 VERIFY( res
.ec
== std::errc
{} );
137 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
138 std::chars_format::scientific
);
139 VERIFY( d
== 0.5e+2 );
140 VERIFY( res
.ptr
== s
.data() + s
.length() - 1 - 3 );
141 VERIFY( res
.ec
== std::errc
{} );
144 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
145 std::chars_format::general
);
146 VERIFY( d
== 0.5e+2 );
147 VERIFY( res
.ptr
== s
.data() + s
.length() - 1 - 3 );
148 VERIFY( res
.ec
== std::errc
{} );
151 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
152 std::chars_format::hex
);
153 VERIFY( d
== 0x0.5Ep0
);
154 VERIFY( res
.ptr
== s
.data() + 4 );
155 VERIFY( res
.ec
== std::errc
{} );
158 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
,
159 std::chars_format::hex
);
160 VERIFY( d
== 0.40625 );
161 VERIFY( res
.ptr
== s
.data() + s
.length() - 3 );
162 VERIFY( res
.ec
== std::errc
{} );
168 // Huge input strings
169 std::string
s(1000, '0');
171 std::from_chars_result res
;
172 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
173 VERIFY( res
.ptr
== s
.data() + s
.length() );
174 VERIFY( res
.ec
== std::errc
{} );
178 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
179 VERIFY( res
.ptr
== s
.data() + s
.length() );
180 VERIFY( res
.ec
== std::errc
{} );
184 auto len
= s
.length();
185 s
+= std::string(1000, 'a');
186 res
= std::from_chars(s
.data(), s
.data() + s
.length(), d
);
187 VERIFY( res
.ptr
== s
.data() + len
);
188 VERIFY( res
.ec
== std::errc
{} );
192 using std::to_string
;
194 #ifdef __GLIBCXX_TYPE_INT_N_0
196 to_string(unsigned __GLIBCXX_TYPE_INT_N_0 val
)
198 using Limits
= std::numeric_limits
<unsigned __GLIBCXX_TYPE_INT_N_0
>;
199 std::string
s(Limits::digits10
+2, '0');
200 for (auto iter
= s
.end(); val
!= 0; val
/= 10)
201 *--iter
= '0' + (val
% 10);
209 std::from_chars_result res
;
214 // Small integer values that are exactly representable
216 for (int i
= 0; i
< 100; ++i
)
218 std::string s
= to_string(i
);
219 int len
= s
.length();
221 const char* s1
= s
.c_str();
222 const char* s1_end
= s1
+ len
;
224 for (auto fmt
: { std::chars_format::fixed
,
225 std::chars_format::general
,
226 std::chars_format::hex
})
228 if (fmt
== std::chars_format::hex
&& i
> 9)
231 res
= std::from_chars(s1
, s1_end
, flt
, fmt
);
232 VERIFY( res
.ec
== std::errc
{} );
233 VERIFY( res
.ptr
== s1_end
);
236 res
= std::from_chars(s1
, s1_end
, dbl
, fmt
);
237 VERIFY( res
.ec
== std::errc
{} );
238 VERIFY( res
.ptr
== s1_end
);
241 res
= std::from_chars(s1
, s1_end
, ldbl
, fmt
);
242 VERIFY( res
.ec
== std::errc
{} );
243 VERIFY( res
.ptr
== s1_end
);
250 // Test single-digit integers with small exponents.
252 const char s2
[] = { '.', *s1
, 'e', '0', '0', '0', '1' };
253 const char* s2_end
= s2
+ sizeof(s2
);
255 const char s3
[] = { *s1
, '0', 'e', '-', '0', '0', '1' };
256 const char* s3_end
= s3
+ sizeof(s3
);
258 for (auto fmt
: { std::chars_format::scientific
,
259 std::chars_format::general
})
261 res
= std::from_chars(s2
, s2_end
, flt
, fmt
);
262 VERIFY( res
.ec
== std::errc
{} );
263 VERIFY( res
.ptr
== s2_end
);
266 res
= std::from_chars(s3
, s3_end
, flt
, fmt
);
267 VERIFY( res
.ec
== std::errc
{} );
268 VERIFY( res
.ptr
== s3_end
);
271 res
= std::from_chars(s2
, s2_end
, dbl
, fmt
);
272 VERIFY( res
.ec
== std::errc
{} );
273 VERIFY( res
.ptr
== s2_end
);
276 res
= std::from_chars(s3
, s3_end
, dbl
, fmt
);
277 VERIFY( res
.ec
== std::errc
{} );
278 VERIFY( res
.ptr
== s3_end
);
281 res
= std::from_chars(s2
, s2_end
, ldbl
, fmt
);
282 VERIFY( res
.ec
== std::errc
{} );
283 VERIFY( res
.ptr
== s2_end
);
286 res
= std::from_chars(s3
, s3_end
, ldbl
, fmt
);
287 VERIFY( res
.ec
== std::errc
{} );
288 VERIFY( res
.ptr
== s3_end
);
294 template<typename FloatT
, typename UIntT
>
298 using Float_limits
= std::numeric_limits
<FloatT
>;
299 using UInt_limits
= std::numeric_limits
<UIntT
>;
301 if (Float_limits::is_iec559
&& Float_limits::digits
< UInt_limits::digits
)
303 #ifdef _GLIBCXX_USE_C99_MATH_TR1
304 std::printf("Testing %d-bit float, using %zu-bit integer\n",
305 Float_limits::digits
+ (int)std::log2(Float_limits::max_exponent
) + 1,
306 sizeof(UIntT
) * __CHAR_BIT__
);
309 std::from_chars_result res
;
312 for (int i
= 0; i
< 10; ++i
)
314 // (1 << digits) - 1 is the maximum value of the mantissa
315 const auto val
= ((UIntT
)1 << Float_limits::digits
) - 1 - i
;
316 std::string s
= to_string(val
);
317 auto len
= s
.length();
318 s
+= "000"; // these should be ignored
319 for (auto fmt
: { std::chars_format::fixed
,
320 std::chars_format::general
})
322 res
= std::from_chars(s
.data(), s
.data() + len
, flt
, fmt
);
323 VERIFY( res
.ec
== std::errc
{} );
324 VERIFY( res
.ptr
== s
.data() + len
);
325 VERIFY( flt
== val
);
328 const auto orig_len
= len
;
332 for (auto fmt
: { std::chars_format::scientific
,
333 std::chars_format::general
})
335 res
= std::from_chars(s
.data(), s
.data() + len
, flt
, fmt
);
336 VERIFY( res
.ec
== std::errc
{} );
337 VERIFY( res
.ptr
== s
.data() + len
);
338 VERIFY( flt
== val
);
340 std::string s2
= s
.substr(0, len
- 5);
341 s2
.insert(s2
.begin() + orig_len
- 1, '.');
342 s2
+= "e000000000001";
343 res
= std::from_chars(s
.data(), s
.data() + len
, flt
, fmt
);
344 VERIFY( res
.ec
== std::errc
{} );
345 VERIFY( res
.ptr
== s
.data() + len
);
346 VERIFY( flt
== val
);
355 test_max_mantissa
<float, unsigned long>();
356 test_max_mantissa
<double, unsigned long long>();
357 #ifdef __GLIBCXX_TYPE_INT_N_0
358 test_max_mantissa
<long double, unsigned __GLIBCXX_TYPE_INT_N_0
>();
366 #if __cpp_lib_to_chars >= 201611L