VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstStrToNum.cpp@ 99775

Last change on this file since 99775 was 98640, checked in by vboxsync, 21 months ago

IPRT/tstStrToNum: Fixed RTStrToDoubleEx testcase bugs. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 30.8 KB
Line 
1/* $Id: tstStrToNum.cpp 98640 2023-02-20 09:37:09Z vboxsync $ */
2/** @file
3 * IPRT Testcase - String To Number Conversion.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/test.h>
42#include <iprt/string.h>
43#include <iprt/stream.h>
44#include <iprt/err.h>
45
46#include <float.h>
47
48
49/*********************************************************************************************************************************
50* Structures and Typedefs *
51*********************************************************************************************************************************/
52struct TstI64
53{
54 const char *psz;
55 unsigned uBase;
56 int rc;
57 int64_t Result;
58};
59
60struct TstU64
61{
62 const char *psz;
63 unsigned uBase;
64 int rc;
65 uint64_t Result;
66};
67
68struct TstI32
69{
70 const char *psz;
71 unsigned uBase;
72 int rc;
73 int32_t Result;
74};
75
76struct TstU32
77{
78 const char *psz;
79 unsigned uBase;
80 int rc;
81 uint32_t Result;
82};
83
84
85struct TstRD
86{
87 const char *psz;
88 unsigned cchMax;
89 int rc;
90 double rd;
91};
92
93struct TstR64
94{
95 const char *psz;
96 unsigned cchMax;
97 int rc;
98 RTFLOAT64U r64;
99};
100
101
102/*********************************************************************************************************************************
103* Defined Constants And Macros *
104*********************************************************************************************************************************/
105#define TEST(Test, Type, Fmt, Fun, iTest) \
106 do \
107 { \
108 Type Result; \
109 int rc = Fun(Test.psz, NULL, Test.uBase, &Result); \
110 if (Result != Test.Result) \
111 RTTestIFailed("'%s' -> " Fmt " expected " Fmt ". (%s/%u)\n", Test.psz, Result, Test.Result, #Fun, iTest); \
112 else if (rc != Test.rc) \
113 RTTestIFailed("'%s' -> rc=%Rrc expected %Rrc. (%s/%u)\n", Test.psz, rc, Test.rc, #Fun, iTest); \
114 } while (0)
115
116
117#define RUN_TESTS(aTests, Type, Fmt, Fun) \
118 do \
119 { \
120 RTTestISub(#Fun); \
121 for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++) \
122 { \
123 TEST(aTests[iTest], Type, Fmt, Fun, iTest); \
124 } \
125 } while (0)
126
127#define FULL_TEST(Test, Type, Fmt, Fun, iTest) \
128 do \
129 { \
130 Type Result; \
131 int rc = Fun(Test.psz, Test.uBase, &Result); \
132 if (Result != Test.Result) \
133 RTTestIFailed("'%s' -> " Fmt " expected " Fmt ". (%s/%u)\n", Test.psz, Result, Test.Result, #Fun, iTest); \
134 else if (rc != Test.rc) \
135 RTTestIFailed("'%s' -> rc=%Rrc expected %Rrc. (%s/%u)\n", Test.psz, rc, Test.rc, #Fun, iTest); \
136 } while (0)
137
138
139#define RUN_FULL_TESTS(aTests, Type, Fmt, Fun) \
140 do \
141 { \
142 RTTestISub(#Fun); \
143 for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++) \
144 { \
145 FULL_TEST(aTests[iTest], Type, Fmt, Fun, iTest); \
146 } \
147 } while (0)
148
149
150
151int main()
152{
153 RTTEST hTest;
154 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTStrToNum", &hTest);
155 if (rcExit != RTEXITCODE_SUCCESS)
156 return rcExit;
157
158 static const struct TstU64 aTstU64[] =
159 {
160 { "0", 0, VINF_SUCCESS, 0 },
161 { "1", 0, VINF_SUCCESS, 1 },
162 { "-1", 0, VWRN_NEGATIVE_UNSIGNED, ~0ULL },
163 { "0x", 0, VWRN_TRAILING_CHARS, 0 },
164 { "0x1", 0, VINF_SUCCESS, 1 },
165 { "0x0fffffffffffffff", 0, VINF_SUCCESS, 0x0fffffffffffffffULL },
166 { "0x0ffffffffffffffffffffff",0, VWRN_NUMBER_TOO_BIG, 0xffffffffffffffffULL },
167 { "0x0ffffffffffffffffffffff", 10 << 8, VINF_SUCCESS, 0x0fffffff },
168 { "asdfasdfasdf", 0, VERR_NO_DIGITS, 0 },
169 { "0x111111111", 0, VINF_SUCCESS, 0x111111111ULL },
170 { "4D9702C5CBD9B778", 16, VINF_SUCCESS, UINT64_C(0x4D9702C5CBD9B778) },
171 };
172 RUN_TESTS(aTstU64, uint64_t, "%#llx", RTStrToUInt64Ex);
173
174 static const struct TstU64 aTstFullU64[] =
175 {
176 { "42", 0, VINF_SUCCESS, 42 },
177 { "42 ", 0, VERR_TRAILING_SPACES, 42 },
178 { "42! ", 0, VERR_TRAILING_CHARS, 42 },
179 { "42 !", 0, VERR_TRAILING_CHARS, 42 },
180 { "42 !", 2<<8, VINF_SUCCESS, 42 },
181 { "42 !", 3<<8, VERR_TRAILING_SPACES, 42 },
182 { "42 !", 4<<8, VERR_TRAILING_CHARS, 42 },
183 { "-1", 0, VWRN_NEGATIVE_UNSIGNED, UINT64_MAX },
184 { "-1 ", 0, VERR_TRAILING_SPACES, UINT64_MAX },
185 { "-1 ", 2<<8, VWRN_NEGATIVE_UNSIGNED, UINT64_MAX },
186 { "-1 ", 3<<8, VERR_TRAILING_SPACES, UINT64_MAX },
187 { "0x0fffffffffffffff", 0, VINF_SUCCESS, 0x0fffffffffffffffULL },
188 { "0x0ffffffffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, 0xffffffffffffffffULL },
189 { "0x0ffffffffffffffffffff ", 0, VERR_TRAILING_SPACES, 0xffffffffffffffffULL },
190 { "0x0ffffffffffffffffffff! ", 0, VERR_TRAILING_CHARS, 0xffffffffffffffffULL },
191 { "0x0ffffffffffffffffffff !", 0, VERR_TRAILING_CHARS, 0xffffffffffffffffULL },
192 { "0x0ffffffffffffffffffff", 10 << 8, VINF_SUCCESS, 0x0fffffff },
193 };
194 RUN_FULL_TESTS(aTstFullU64, uint64_t, "%#llx", RTStrToUInt64Full);
195
196 static const struct TstI64 aTstI64[] =
197 {
198 { "0", 0, VINF_SUCCESS, 0 },
199 { "1", 0, VINF_SUCCESS, 1 },
200 { "-1", 0, VINF_SUCCESS, -1 },
201 { "-1", 10, VINF_SUCCESS, -1 },
202 { "-31", 0, VINF_SUCCESS, -31 },
203 { "-31", 10, VINF_SUCCESS, -31 },
204 { "-32", 0, VINF_SUCCESS, -32 },
205 { "-33", 0, VINF_SUCCESS, -33 },
206 { "-64", 0, VINF_SUCCESS, -64 },
207 { "-127", 0, VINF_SUCCESS, -127 },
208 { "-128", 0, VINF_SUCCESS, -128 },
209 { "-129", 0, VINF_SUCCESS, -129 },
210 { "-254", 0, VINF_SUCCESS, -254 },
211 { "-255", 0, VINF_SUCCESS, -255 },
212 { "-256", 0, VINF_SUCCESS, -256 },
213 { "-257", 0, VINF_SUCCESS, -257 },
214 { "-511", 0, VINF_SUCCESS, -511 },
215 { "-512", 0, VINF_SUCCESS, -512 },
216 { "-513", 0, VINF_SUCCESS, -513 },
217 { "-1023", 0, VINF_SUCCESS, -1023 },
218 { "-1023", 0, VINF_SUCCESS, -1023 },
219 { "-1023", 0, VINF_SUCCESS, -1023},
220 { "-1023", 10, VINF_SUCCESS, -1023 },
221 { "-4564678", 0, VINF_SUCCESS, -4564678 },
222 { "-4564678", 10, VINF_SUCCESS, -4564678 },
223 { "-1234567890123456789", 0, VINF_SUCCESS, -1234567890123456789LL },
224 { "-1234567890123456789", 10, VINF_SUCCESS, -1234567890123456789LL },
225 { "0x", 0, VWRN_TRAILING_CHARS, 0 },
226 { "0x1", 0, VINF_SUCCESS, 1 },
227 { "0x1", 10, VWRN_TRAILING_CHARS, 0 },
228 { "0x1", 16, VINF_SUCCESS, 1 },
229 { "0x0fffffffffffffff", 0, VINF_SUCCESS, 0x0fffffffffffffffULL },
230 { "0x7fffffffffffffff", 0, VINF_SUCCESS, 0x7fffffffffffffffULL },
231 { "0xffffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, -1 },
232 { "0x01111111111111111111111",0, VWRN_NUMBER_TOO_BIG, 0x1111111111111111ULL },
233 { "0x02222222222222222222222",0, VWRN_NUMBER_TOO_BIG, 0x2222222222222222ULL },
234 { "0x03333333333333333333333",0, VWRN_NUMBER_TOO_BIG, 0x3333333333333333ULL },
235 { "0x04444444444444444444444",0, VWRN_NUMBER_TOO_BIG, 0x4444444444444444ULL },
236 { "0x07777777777777777777777",0, VWRN_NUMBER_TOO_BIG, 0x7777777777777777ULL },
237 { "0x07f7f7f7f7f7f7f7f7f7f7f",0, VWRN_NUMBER_TOO_BIG, 0x7f7f7f7f7f7f7f7fULL },
238 { "0x0ffffffffffffffffffffff",0, VWRN_NUMBER_TOO_BIG, (int64_t)0xffffffffffffffffULL },
239 { "0x0ffffffffffffffffffffff", 10 << 8, VINF_SUCCESS, INT64_C(0x0fffffff) },
240 { "0x0ffffffffffffffffffffff", 18 << 8, VINF_SUCCESS, INT64_C(0x0fffffffffffffff) },
241 { "0x0ffffffffffffffffffffff", 19 << 8, VWRN_NUMBER_TOO_BIG, -1 },
242 { "asdfasdfasdf", 0, VERR_NO_DIGITS, 0 },
243 { "0x111111111", 0, VINF_SUCCESS, 0x111111111ULL },
244 };
245 RUN_TESTS(aTstI64, int64_t, "%#lld", RTStrToInt64Ex);
246
247 static const struct TstI64 aTstI64Full[] =
248 {
249 { "1", 0, VINF_SUCCESS, 1 },
250 { "1 ", 0, VERR_TRAILING_SPACES, 1 },
251 { "1! ", 0, VERR_TRAILING_CHARS, 1 },
252 { "1 !", 0, VERR_TRAILING_CHARS, 1 },
253 { "1 !", 1<<8, VINF_SUCCESS, 1 },
254 { "1 !", 2<<8, VERR_TRAILING_SPACES, 1 },
255 { "1 !", 3<<8, VERR_TRAILING_CHARS, 1 },
256 { "0xffffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, -1 },
257 { "0xffffffffffffffff ", 0, VERR_TRAILING_SPACES, -1 },
258 { "0xffffffffffffffff!", 0, VERR_TRAILING_CHARS, -1 },
259 { "0xffffffffffffffff !", 18<<8, VWRN_NUMBER_TOO_BIG, -1 },
260 { "0xffffffffffffffff !", 19<<8, VERR_TRAILING_SPACES, -1 },
261 { "0xffffffffffffffff !", 20<<8, VERR_TRAILING_CHARS, -1 },
262 };
263 RUN_FULL_TESTS(aTstI64Full, int64_t, "%#lld", RTStrToInt64Full);
264
265
266 static const struct TstI32 aTstI32[] =
267 {
268 { "0", 0, VINF_SUCCESS, 0 },
269 { "1", 0, VINF_SUCCESS, 1 },
270 { "-1", 0, VINF_SUCCESS, -1 },
271 { "-1", 10, VINF_SUCCESS, -1 },
272 { "-31", 0, VINF_SUCCESS, -31 },
273 { "-31", 10, VINF_SUCCESS, -31 },
274 { "-32", 0, VINF_SUCCESS, -32 },
275 { "-33", 0, VINF_SUCCESS, -33 },
276 { "-64", 0, VINF_SUCCESS, -64 },
277 { "-127", 0, VINF_SUCCESS, -127 },
278 { "-128", 0, VINF_SUCCESS, -128 },
279 { "-129", 0, VINF_SUCCESS, -129 },
280 { "-254", 0, VINF_SUCCESS, -254 },
281 { "-255", 0, VINF_SUCCESS, -255 },
282 { "-256", 0, VINF_SUCCESS, -256 },
283 { "-257", 0, VINF_SUCCESS, -257 },
284 { "-511", 0, VINF_SUCCESS, -511 },
285 { "-512", 0, VINF_SUCCESS, -512 },
286 { "-513", 0, VINF_SUCCESS, -513 },
287 { "-1023", 0, VINF_SUCCESS, -1023 },
288 { "-1023", 0, VINF_SUCCESS, -1023 },
289 { "-1023", 0, VINF_SUCCESS, -1023},
290 { "-1023", 10, VINF_SUCCESS, -1023 },
291 { "-4564678", 0, VINF_SUCCESS, -4564678 },
292 { "-4564678", 10, VINF_SUCCESS, -4564678 },
293 { "4564678", 0, VINF_SUCCESS, 4564678 },
294 { "4564678", 10, VINF_SUCCESS, 4564678 },
295 { "-1234567890123456789", 0, VWRN_NUMBER_TOO_BIG, (int32_t)((uint64_t)INT64_C(-1234567890123456789) & UINT32_MAX) },
296 { "-1234567890123456789", 10, VWRN_NUMBER_TOO_BIG, (int32_t)((uint64_t)INT64_C(-1234567890123456789) & UINT32_MAX) },
297 { "1234567890123456789", 0, VWRN_NUMBER_TOO_BIG, (int32_t)(INT64_C(1234567890123456789) & UINT32_MAX) },
298 { "1234567890123456789", 10, VWRN_NUMBER_TOO_BIG, (int32_t)(INT64_C(1234567890123456789) & UINT32_MAX) },
299 { "0x", 0, VWRN_TRAILING_CHARS, 0 },
300 { "0x1", 0, VINF_SUCCESS, 1 },
301 { "0x1", 10, VWRN_TRAILING_CHARS, 0 },
302 { "0x1", 16, VINF_SUCCESS, 1 },
303 { "0x7fffffff", 0, VINF_SUCCESS, 0x7fffffff },
304 { "0x80000000", 0, VWRN_NUMBER_TOO_BIG, INT32_MIN },
305 { "0xffffffff", 0, VWRN_NUMBER_TOO_BIG, -1 },
306 { "0x0fffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, (int32_t)0xffffffff },
307 { "0x01111111111111111111111",0, VWRN_NUMBER_TOO_BIG, 0x11111111 },
308 { "0x0ffffffffffffffffffffff",0, VWRN_NUMBER_TOO_BIG, (int32_t)0xffffffff },
309 { "0x0ffffffffffffffffffffff", 10 << 8, VINF_SUCCESS, 0x0fffffff },
310 { "0x0ffffffffffffffffffffff", 11 << 8, VWRN_NUMBER_TOO_BIG, -1 },
311 { "asdfasdfasdf", 0, VERR_NO_DIGITS, 0 },
312 { "0x1111111", 0, VINF_SUCCESS, 0x01111111 },
313 };
314 RUN_TESTS(aTstI32, int32_t, "%#d", RTStrToInt32Ex);
315
316 static const struct TstU32 aTstU32[] =
317 {
318 { "0", 0, VINF_SUCCESS, 0 },
319 { "1", 0, VINF_SUCCESS, 1 },
320 /// @todo { "-1", 0, VWRN_NEGATIVE_UNSIGNED, ~0 }, - no longer true. bad idea?
321 { "-1", 0, VWRN_NUMBER_TOO_BIG, ~0U },
322 { "0x", 0, VWRN_TRAILING_CHARS, 0 },
323 { "0x1", 0, VINF_SUCCESS, 1 },
324 { "0x1 ", 0, VWRN_TRAILING_SPACES, 1 },
325 { "0x0fffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, 0xffffffffU },
326 { "0x0ffffffffffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, 0xffffffffU },
327 { "asdfasdfasdf", 0, VERR_NO_DIGITS, 0 },
328 { "0x1111111", 0, VINF_SUCCESS, 0x1111111 },
329 };
330 RUN_TESTS(aTstU32, uint32_t, "%#x", RTStrToUInt32Ex);
331
332
333 static const struct TstU32 aTstFullU32[] =
334 {
335 { "0", 0, VINF_SUCCESS, 0 },
336 { "0x0fffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, 0xffffffffU },
337 { "0x0fffffffffffffffffffff", 0, VWRN_NUMBER_TOO_BIG, 0xffffffffU },
338 { "asdfasdfasdf", 0, VERR_NO_DIGITS, 0 },
339 { "42 ", 0, VERR_TRAILING_SPACES, 42 },
340 { "42 ", 2<<8, VINF_SUCCESS, 42 },
341 { "42! ", 0, VERR_TRAILING_CHARS, 42 },
342 { "42! ", 2<<8, VINF_SUCCESS, 42 },
343 { "42 !", 0, VERR_TRAILING_CHARS, 42 },
344 { "42 !", 2<<8, VINF_SUCCESS, 42 },
345 { "42 !", 3<<8, VERR_TRAILING_SPACES, 42 },
346 { "42 !", 4<<8, VERR_TRAILING_CHARS, 42 },
347 { "0x0fffffffffffffffffffff ", 0, VERR_TRAILING_SPACES, 0xffffffffU },
348 { "0x0fffffffffffffffffffff !", 0, VERR_TRAILING_CHARS, 0xffffffffU },
349 };
350 RUN_FULL_TESTS(aTstFullU32, uint32_t, "%#x", RTStrToUInt32Full);
351
352 /*
353 * Test the some hex stuff too.
354 */
355 RTTestSub(hTest, "RTStrConvertHexBytesEx");
356 static const struct
357 {
358 const char *pszHex;
359 size_t cbOut;
360 size_t offNext;
361 uint8_t bLast;
362 bool fColon;
363 int rc;
364 } s_aConvertHexTests[] =
365 {
366 { "00", 1, 2, 0x00, true, VINF_SUCCESS },
367 { "00", 1, 2, 0x00, false, VINF_SUCCESS },
368 { "000102", 3, 6, 0x02, true, VINF_SUCCESS },
369 { "00019", 2, 4, 0x01, false, VERR_UNEVEN_INPUT },
370 { "00019", 2, 4, 0x01, true, VERR_UNEVEN_INPUT },
371 { "0001:9", 3, 6, 0x09, true, VINF_SUCCESS},
372 { "000102", 3, 6, 0x02, false, VINF_SUCCESS },
373 { "0:1", 2, 3, 0x01, true, VINF_SUCCESS },
374 { ":", 2, 1, 0x00, true, VINF_SUCCESS },
375 { "0:01", 2, 4, 0x01, true, VINF_SUCCESS },
376 { "00:01", 2, 5, 0x01, true, VINF_SUCCESS },
377 { ":1:2:3:4:5", 6, 10, 0x05, true, VINF_SUCCESS },
378 { ":1:2:3::5", 6, 9, 0x05, true, VINF_SUCCESS },
379 { ":1:2:3:4:", 6, 9, 0x00, true, VINF_SUCCESS },
380 };
381 for (unsigned i = 0; i < RT_ELEMENTS(s_aConvertHexTests); i++)
382 {
383 uint8_t abBuf[1024];
384 memset(abBuf, 0xf6, sizeof(abBuf));
385 const char *pszExpectNext = &s_aConvertHexTests[i].pszHex[s_aConvertHexTests[i].offNext];
386 const char *pszNext = "";
387 size_t cbReturned = 77777;
388 int rc = RTStrConvertHexBytesEx(s_aConvertHexTests[i].pszHex, abBuf, s_aConvertHexTests[i].cbOut,
389 s_aConvertHexTests[i].fColon ? RTSTRCONVERTHEXBYTES_F_SEP_COLON : 0,
390 &pszNext, &cbReturned);
391 if ( rc != s_aConvertHexTests[i].rc
392 || pszNext != pszExpectNext
393 || abBuf[s_aConvertHexTests[i].cbOut - 1] != s_aConvertHexTests[i].bLast
394 )
395 RTTestFailed(hTest, "RTStrConvertHexBytesEx/#%u %s -> %Rrc %p %#zx %#02x, expected %Rrc %p %#zx %#02x\n",
396 i, s_aConvertHexTests[i].pszHex,
397 rc, pszNext, cbReturned, abBuf[s_aConvertHexTests[i].cbOut - 1],
398 s_aConvertHexTests[i].rc, pszExpectNext, s_aConvertHexTests[i].cbOut, s_aConvertHexTests[i].bLast);
399 }
400
401
402 /*
403 * Floating point string conversion.
404 */
405#ifdef RT_OS_WINDOWS /** @todo debug elsewhere */
406 char szActual[128], szExpect[128];
407
408 RTTestSub(hTest, "RTStrToDoubleEx");
409 static const struct TstRD s_aTstDouble[] =
410 {
411 { "1", 0, VINF_SUCCESS, 1.0 },
412 { "2.0", 0, VINF_SUCCESS, 2.0 },
413 { "2.0000", 0, VINF_SUCCESS, 2.0 },
414 { "-2.0000", 0, VINF_SUCCESS, -2.0 },
415 { "-2.0000", 1, VERR_NO_DIGITS, -0.0 },
416 { "-2.0000", 2, VINF_SUCCESS, -2.0 },
417 { "0.5", 0, VINF_SUCCESS, 0.5 },
418 { "1.5", 0, VINF_SUCCESS, 1.5 },
419 { "42.", 0, VINF_SUCCESS, 42.0 },
420 { "243.598605987", 0, VINF_SUCCESS, 243.598605987 },
421 { "3.14159265358979323846", 0, VINF_SUCCESS, 3.14159265358979323846 },
422 { "3.1415926535897932384626433832", 0, VINF_SUCCESS, 3.14159265358979323846 },
423 { "2.9979245800e+008", 0, VINF_SUCCESS, 299792458.0 }, /* speed of light (c) */
424 { "1.602176487e-19", 0, VINF_SUCCESS, 1.602176487e-19 }, /* electron volt (eV) */
425 { "6.62606896e-34", 0, VINF_SUCCESS, 6.62606896e-34 }, /* Planck's constant (h) */
426 { "6.02214199e+23", 0, VINF_SUCCESS, 6.02214199e23 }, /* Avogadro's number (Na) */
427 { "1.66053e-0", 0, VINF_SUCCESS, 1.66053e-0 },
428 { "1.66053e-1", 0, VINF_SUCCESS, 1.66053e-1 },
429 { "1.66053e-2", 0, VINF_SUCCESS, 1.66053e-2 },
430 { "1.66053e-3", 0, VINF_SUCCESS, 1.66053e-3 },
431 { "1.66053e-4", 0, VINF_SUCCESS, 1.66053e-4 },
432 { "1.66053e-5", 0, VINF_SUCCESS, 1.66053e-5 },
433 { "1.66053e-6", 0, VINF_SUCCESS, 1.66053e-6 },
434 { "1.660538780e-27", 0, VINF_SUCCESS, 1.660538780e-27 },
435 { "1.660538781e-27", 0, VINF_SUCCESS, 1.660538781e-27 },
436 { "1.660538782e-27", 0, VINF_SUCCESS, 1.660538782e-27 }, /* Unified atomic mass (amu) [rounding issue with simple scale10 code] */
437 { "1.660538783e-27", 0, VINF_SUCCESS, 1.660538783e-27 },
438 { "1.660538784e-27", 0, VINF_SUCCESS, 1.660538784e-27 },
439 { "1.660538785e-27", 0, VINF_SUCCESS, 1.660538785e-27 },
440 { "1e1", 0, VINF_SUCCESS, 1.0e1 },
441 { "99e98", 0, VINF_SUCCESS, 99.0e98 },
442 { "1.2398039e206", 0, VINF_SUCCESS, 1.2398039e206 },
443 { "-1.2398039e-205", 0, VINF_SUCCESS, -1.2398039e-205 },
444 { "-1.2398039e-305", 0, VINF_SUCCESS, -1.2398039e-305 },
445 { "-1.2398039e-306", 0, VINF_SUCCESS, -1.2398039e-306 }, /* RTStrFormatR64 get weird about these numbers... */
446 { "-1.2398039e-307", 0, VINF_SUCCESS, -1.2398039e-307 },
447 { "-1.2398039e-308", 0, VWRN_FLOAT_UNDERFLOW, -1.2398039e-308 }, /* subnormal */
448 { "-1.2398039e-309", 0, VWRN_FLOAT_UNDERFLOW, -1.2398039e-309 }, /* subnormal */
449 { "-1.2398039e-310", 0, VWRN_FLOAT_UNDERFLOW, -1.2398039e-310 }, /* subnormal */
450 { "-1.2398039e-315", 0, VWRN_FLOAT_UNDERFLOW, -1.2398039e-315 }, /* subnormal */
451 { "-1.2398039e-323", 0, VWRN_FLOAT_UNDERFLOW, -1.2398039e-323 }, /* subnormal */
452#if 0 /* problematic in softfloat mode */
453 { "-1.2398039e-324", 0, VWRN_FLOAT_UNDERFLOW, -1.2398039e-324 }, /* subnormal */
454#endif
455 { "-1.2398039e-325", 0, VERR_FLOAT_UNDERFLOW, -0.0 },
456 { "1.7976931348623158e+308", 0, VINF_SUCCESS, +DBL_MAX },
457 { "-1.7976931348623158e+308", 0, VINF_SUCCESS, -DBL_MAX },
458 { "2.2250738585072014e-308", 0, VINF_SUCCESS, +DBL_MIN },
459 { "-2.2250738585072014e-308", 0, VINF_SUCCESS, -DBL_MIN },
460 { "-2.2250738585072010e-308", 0, VWRN_FLOAT_UNDERFLOW, -2.2250738585072010E-308 }, /* subnormal close to -DBL_MIN */
461#if __cplusplus >= 201700
462 { "0x1", 0, VINF_SUCCESS, 0x1.0p0 },
463 { "0x2", 0, VINF_SUCCESS, 0x2.0p0 },
464 { "0x3", 0, VINF_SUCCESS, 0x3.0p0 },
465 { "0x3p1", 0, VINF_SUCCESS, 0x3.0p1 },
466 { "0x9.2p42", 0, VINF_SUCCESS, 0x9.2p42 },
467 { "-0x48f0405.24986e5f794bp42", 0, VINF_SUCCESS, -0x48f0405.24986e5f794bp42 },
468#endif
469 };
470 for (unsigned i = 0; i < RT_ELEMENTS(s_aTstDouble); i++)
471 {
472 //RTTestPrintf(hTest,RTTESTLVL_ALWAYS, "----- #%u: %s\n", i, s_aTstDouble[i].psz);
473 RTFLOAT64U uRes = RTFLOAT64U_INIT_ZERO(1);
474 char *pszNext = (char *)42;
475 int rc = RTStrToDoubleEx(s_aTstDouble[i].psz, &pszNext, s_aTstDouble[i].cchMax, &uRes.rd);
476
477 RTFLOAT64U uExpect;
478 uExpect.rd = s_aTstDouble[i].rd;
479 if (rc != s_aTstDouble[i].rc || !RTFLOAT64U_ARE_IDENTICAL(&uRes, &uExpect))
480 {
481 RTStrFormatR64(szActual, sizeof(szActual), &uRes, 0, 0, RTSTR_F_SPECIAL);
482 RTStrFormatR64(szExpect, sizeof(szExpect), &uExpect, 0, 0, RTSTR_F_SPECIAL);
483 RTTestFailed(hTest, "RTStrToDoubleEx/%#u: '%s' L %u -> %Rrc & %s, expected %Rrc & %s\n",
484 i, s_aTstDouble[i].psz, s_aTstDouble[i].cchMax, rc, szActual, s_aTstDouble[i].rc, szExpect);
485 }
486 }
487
488 static const struct TstR64 s_aTstR64[] =
489 {
490 { "Inf", 0, VINF_SUCCESS, RTFLOAT64U_INIT_INF(0) },
491 { "+Inf", 0, VINF_SUCCESS, RTFLOAT64U_INIT_INF(0) },
492 { "-Inf", 0, VINF_SUCCESS, RTFLOAT64U_INIT_INF(1) },
493 { "-Inf0", 0, VWRN_TRAILING_CHARS, RTFLOAT64U_INIT_INF(1) },
494 { "-Inf ", 0, VWRN_TRAILING_SPACES, RTFLOAT64U_INIT_INF(1) },
495 { "-Inf 0", 0, VWRN_TRAILING_CHARS, RTFLOAT64U_INIT_INF(1) },
496 { "-Inf 0", 1, VERR_NO_DIGITS, RTFLOAT64U_INIT_ZERO(1) },
497 { "-Inf 0", 2, VERR_NO_DIGITS, RTFLOAT64U_INIT_ZERO(1) },
498 { "-Inf 0", 3, VERR_NO_DIGITS, RTFLOAT64U_INIT_ZERO(1) },
499 { "-Inf 0", 4, VINF_SUCCESS, RTFLOAT64U_INIT_INF(1) },
500 { "Nan", 0, VINF_SUCCESS, RTFLOAT64U_INIT_QNAN(0) },
501 { "+Nan", 0, VINF_SUCCESS, RTFLOAT64U_INIT_QNAN(0) },
502 { "+Nan(1)", 0, VINF_SUCCESS, RTFLOAT64U_INIT_QNAN_EX(0, 1) },
503 { "-NaN", 0, VINF_SUCCESS, RTFLOAT64U_INIT_QNAN(1) },
504 { "-nAn(1)", 0, VINF_SUCCESS, RTFLOAT64U_INIT_QNAN_EX(1, 1) },
505 { "-nAn(q)", 0, VINF_SUCCESS, RTFLOAT64U_INIT_QNAN(1) },
506 { "-nAn(s)", 0, VINF_SUCCESS, RTFLOAT64U_INIT_SNAN(1) },
507 { "-nAn(_sig)", 0, VINF_SUCCESS, RTFLOAT64U_INIT_SNAN(1) },
508 { "-nAn(22420102_sig)12", 0, VWRN_TRAILING_CHARS, RTFLOAT64U_INIT_SNAN_EX(1, 0x22420102) },
509 { "-nAn(22420102_sig) ", 0, VWRN_TRAILING_SPACES, RTFLOAT64U_INIT_SNAN_EX(1, 0x22420102) },
510 { "-nAn(22420102_sig) 2", 0, VWRN_TRAILING_CHARS, RTFLOAT64U_INIT_SNAN_EX(1, 0x22420102) },
511 { "-1.2398039e-500", 0, VERR_FLOAT_UNDERFLOW, RTFLOAT64U_INIT_ZERO(1) },
512 { "-1.2398039e-5000", 0, VERR_FLOAT_UNDERFLOW, RTFLOAT64U_INIT_ZERO(1) },
513 { "-1.2398039e-50000", 0, VERR_FLOAT_UNDERFLOW, RTFLOAT64U_INIT_ZERO(1) },
514 { "-1.2398039e-500000", 0, VERR_FLOAT_UNDERFLOW, RTFLOAT64U_INIT_ZERO(1) },
515 { "-1.2398039e-500000000", 0, VERR_FLOAT_UNDERFLOW, RTFLOAT64U_INIT_ZERO(1) },
516 { "+1.7976931348623159e+308", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(0) },
517 { "-1.7976931348623159e+308", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
518 { "-1.2398039e+309", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
519 { "-1.2398039e+350", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
520 { "-1.2398039e+400", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
521 { "-1.2398039e+450", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
522 { "-1.2398039e+500", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
523 { "-1.2398039e+5000", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
524 { "-1.2398039e+50000", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
525 { "-1.2398039e+500000", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
526 { "-1.2398039e+5000000000", 0, VERR_FLOAT_OVERFLOW, RTFLOAT64U_INIT_INF(1) },
527 };
528 for (unsigned i = 0; i < RT_ELEMENTS(s_aTstR64); i++)
529 {
530 //RTTestPrintf(hTest,RTTESTLVL_ALWAYS, "----- #%u: %s\n", i, s_aTstDouble[i].psz);
531 RTFLOAT64U uRes = RTFLOAT64U_INIT_ZERO(1);
532 char *pszNext = (char *)42;
533 int rc = RTStrToDoubleEx(s_aTstR64[i].psz, &pszNext, s_aTstR64[i].cchMax, &uRes.rd);
534
535 if (rc != s_aTstR64[i].rc || !RTFLOAT64U_ARE_IDENTICAL(&uRes, &s_aTstR64[i].r64))
536 {
537 RTStrFormatR64(szActual, sizeof(szActual), &uRes, 0, 0, RTSTR_F_SPECIAL);
538 RTStrFormatR64(szExpect, sizeof(szExpect), &s_aTstR64[i].r64, 0, 0, RTSTR_F_SPECIAL);
539 RTTestFailed(hTest, "RTStrToDoubleEx/%#u: '%s' L %u -> %Rrc & %s, expected %Rrc & %s\n",
540 i, s_aTstR64[i].psz, s_aTstR64[i].cchMax, rc, szActual, s_aTstR64[i].rc, szExpect);
541 }
542 }
543#endif /* RT_OS_WINDOWS - debug elsewhere first */
544
545 /*
546 * Summary.
547 */
548 return RTTestSummaryAndDestroy(hTest);
549}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette