VirtualBox

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

Last change on this file since 96205 was 96152, checked in by vboxsync, 2 years ago

IPRT: Added RTStrToFloat, RTStrToDouble and RTStrToLongDouble. Still some rought edges; only tested on Windows. bugref:10261

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