]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/20_util/to_chars/long_double.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / to_chars / long_double.cc
CommitLineData
99dee823 1// Copyright (C) 2020-2021 Free Software Foundation, Inc.
3c57e692
PP
2//
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)
7// any later version.
8
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.
13
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/>.
17
18// <charconv> is supported in C++14 as a GNU extension, but this test uses C++17
19// hexadecimal floating-point literals.
20// { dg-do run { target c++17 } }
21// { dg-xfail-run-if "Ryu needs __int128" { large_long_double && { ! int128 } } }
6a31d47e 22// { dg-require-effective-target ieee-floats }
3c57e692
PP
23
24#include <charconv>
25
26#include <cmath>
27#include <cstring>
28#include <iterator>
29#include <limits>
30
31#include <testsuite_hooks.h>
32
33using namespace std;
34
35// The long double overloads of std::to_chars currently just go through printf
36// (except for the hexadecimal formatting).
37
38// Test our hand-written hexadecimal formatting implementation.
39void
40test01()
41{
42 const long double hex_testcases[]
43 = { nextdownl(numeric_limits<long double>::max()),
44 nextupl(numeric_limits<long double>::min()),
45 42.0L,
46 0x1.2p+0L,
47 0x1.23p+0L,
48 0x1.234p+0L,
49 0x1.2345p+0L,
50 0x1.23456p+0L,
51 0x1.234567p+0L,
52 0x1.2345678p+0L,
53 0x1.23456789p+0L,
54 0x1.23456789p+0L,
55 0x1.23456789ap+0L,
56 0x1.23456789abp+0L,
57 0x1.23456789abcp+0L,
58 0x1.23456789abcdp+0L,
59 0x1.23456789abcdep+0L,
60 0x1.23456789abcdefp+0L,
61 0x1.23456789abcdef0p+0L,
62 0x1.23456789abcdef01p+0L,
63 0x1.23456789abcdef012p+0L,
64 0x1.23456789abcdef0123p+0L,
65 0x1.23456789abcdef01234p+0L,
66 0x1.23456789abcdef012345p+0L,
67 0x1.23456789abcdef0123456p+0L,
68 0x1.23456789abcdef01234567p+0L,
69 0x1.23456789abcdef012345678p+0L,
70 0x1.23456789abcdef0123456789p+0L,
71 0x1.23456789abcdef0123456789ap+0L,
72 0x1.23456789abcdef0123456789abp+0L,
73 0x1.23456789abcdef0123456789abcp+0L,
74 0x1.23456789abcdef0123456789abcdp+0L,
75 };
76
77 for (int exponent : {-11000, -3000, -300, -50, -7, 0, 7, 50, 300, 3000, 11000})
78 for (long double testcase : hex_testcases)
79 {
80 testcase = ldexpl(testcase, exponent);
81 if (testcase == 0.0L || isinf(testcase))
82 continue;
83
84 char to_chars_buffer[1024], printf_buffer[1024];
85 memset(to_chars_buffer, '\0', sizeof(to_chars_buffer));
86 memset(printf_buffer, '\0', sizeof(printf_buffer));
87
88 auto result = to_chars(begin(to_chars_buffer), end(to_chars_buffer),
89 testcase, chars_format::hex);
90 VERIFY( result.ec == errc{} );
91 *result.ptr = '\0';
92 sprintf(printf_buffer, "%La", testcase);
93 VERIFY( !strcmp(to_chars_buffer, printf_buffer+strlen("0x")) );
94
95 {
96 // Verify that the nearby values have a different shortest form.
97 testcase = nextdownl(testcase);
98 result = to_chars(begin(to_chars_buffer), end(to_chars_buffer),
99 testcase, chars_format::hex);
100 VERIFY( result.ec == errc{} );
101 *result.ptr = '\0';
102 VERIFY( strcmp(to_chars_buffer, printf_buffer+strlen("0x")) != 0);
103 sprintf(printf_buffer, "%La", testcase);
104 VERIFY( !strcmp(to_chars_buffer, printf_buffer+strlen("0x")) );
105
106 testcase = nextupl(nextupl(testcase));
107 result = to_chars(begin(to_chars_buffer), end(to_chars_buffer),
108 testcase, chars_format::hex);
109 VERIFY( result.ec == errc{} );
110 *result.ptr = '\0';
111 VERIFY( strcmp(to_chars_buffer, printf_buffer+strlen("0x")) != 0);
112 sprintf(printf_buffer, "%La", testcase);
113 VERIFY( !strcmp(to_chars_buffer, printf_buffer+strlen("0x")) );
114
115 testcase = nextdownl(testcase);
116 }
117
118 for (int precision = -1; precision < 50; precision++)
119 {
120 result = to_chars(begin(to_chars_buffer), end(to_chars_buffer),
121 testcase, chars_format::hex, precision);
122 VERIFY( result.ec == errc{} );
123 *result.ptr = '\0';
124 sprintf(printf_buffer, "%.*La", precision, testcase);
125 VERIFY( !strcmp(to_chars_buffer, printf_buffer+strlen("0x")) );
126 }
127 }
128}
129
130// Test the rest of the formatting modes, which go through printf.
131void
132test02()
133{
134 const long double growth_factor = 1.442695040888963407359924681001892137L;
135 for (chars_format fmt : {chars_format::fixed, chars_format::scientific,
136 chars_format::general})
137 for (long double __value = 1.0L, count = 0; !isinf(__value);
138 ++count <= 100.0L ? __value *= growth_factor : __value *= __value)
139 for (const long double value : {__value, 1.0L/__value})
140 {
141 for (const int precision : {-1, 0, 10, 100, 10000})
142 {
143 const char* const printf_specifier
144 = (fmt == chars_format::fixed ? "%.*Lf"
145 : fmt == chars_format::scientific ? "%.*Le"
146 : fmt == chars_format::general ? "%.*Lg"
147 : nullptr);
148 unsigned output_length = snprintf(nullptr, 0, printf_specifier,
149 precision, value);
150
151 char printf_buffer[output_length+1];
152 snprintf(printf_buffer, output_length+1, printf_specifier,
153 precision, value);
154
155 char to_chars_buffer[output_length];
156 auto result = to_chars(to_chars_buffer,
157 to_chars_buffer+output_length,
158 value, fmt, precision);
159 VERIFY( result.ec == errc{} );
160 VERIFY( !memcmp(printf_buffer, to_chars_buffer, output_length) );
161
162 result = to_chars(to_chars_buffer,
163 to_chars_buffer+output_length-1,
164 value, fmt, precision);
165 VERIFY( result.ec == errc::value_too_large );
166 }
167
168 // Verify that the nearby values have a different shortest form.
169 char to_chars_buffer[50000];
170 auto result = to_chars(begin(to_chars_buffer), end(to_chars_buffer),
171 value, fmt);
172 VERIFY( result.ec == errc{} );
173 *result.ptr = '\0';
174 char nearby_buffer[50000];
175 {
176 const long double smaller = nextdownl(value);
177 result = to_chars(begin(nearby_buffer), end(nearby_buffer),
178 smaller, fmt);
179 VERIFY( result.ec == errc{} );
180 *result.ptr = '\0';
181 VERIFY( strcmp(to_chars_buffer, nearby_buffer) != 0 );
182 }
183
184 {
185 long double larger = nextupl(value);
186 result = to_chars(begin(nearby_buffer), end(nearby_buffer),
187 larger, fmt);
188 VERIFY( result.ec == errc{} );
189 *result.ptr = '\0';
190 VERIFY( strcmp(to_chars_buffer, nearby_buffer) != 0 );
191 }
192 }
193}
194
195int
196main()
197{
198 test01();
199 test02();
200}