VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRand.cpp@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 5 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.2 KB
Line 
1/* $Id: tstRand.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT - Testcase for the RTRand API.
4 */
5
6/*
7 * Copyright (C) 2008-2019 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/rand.h>
32#include <iprt/errcore.h>
33#include <iprt/stream.h>
34#include <iprt/initterm.h>
35#include <iprt/string.h>
36#include <iprt/assert.h>
37
38
39/*********************************************************************************************************************************
40* Structures and Typedefs *
41*********************************************************************************************************************************/
42typedef struct TSTMEMAUTOPTRSTRUCT
43{
44 uint32_t a;
45 uint32_t b;
46 uint32_t c;
47} TSTMEMAUTOPTRSTRUCT;
48
49
50/*********************************************************************************************************************************
51* Defined Constants And Macros *
52*********************************************************************************************************************************/
53#define CHECK_EXPR(expr) \
54 do { bool const f = !!(expr); if (RT_UNLIKELY(!f)) { RTPrintf("tstRand(%d): %s!\n", __LINE__, #expr); g_cErrors++; } } while (0)
55#define CHECK_EXPR_MSG(expr, msg) \
56 do { \
57 bool const f = !!(expr); \
58 if (RT_UNLIKELY(!f)) { \
59 RTPrintf("tstRand(%d): %s!\n", __LINE__, #expr); \
60 RTPrintf("tstRand: "); \
61 RTPrintf msg; \
62 if (++g_cErrors > 25) return 1; \
63 } \
64 } while (0)
65
66
67#define TST_RAND_SAMPLE_RANGES 16
68
69
70/*********************************************************************************************************************************
71* Global Variables *
72*********************************************************************************************************************************/
73static unsigned g_cErrors = 0;
74
75
76static void tstRandCheckDist(uint32_t *pacHits, unsigned iTest)
77{
78 RTPrintf("tstRand:");
79 uint32_t iMin = UINT32_MAX;
80 uint32_t iMax = 0;
81 uint32_t iAvg = 0;
82 for (unsigned iRange = 0; iRange < TST_RAND_SAMPLE_RANGES; iRange++)
83 {
84 RTPrintf(" %04RX32", pacHits[iRange]);
85 if (iMax < pacHits[iRange])
86 iMax = pacHits[iRange];
87 if (iMin > pacHits[iRange])
88 iMin = pacHits[iRange];
89 iAvg += pacHits[iRange];
90 }
91 iAvg /= TST_RAND_SAMPLE_RANGES;
92 RTPrintf(" min=%RX32 (%%%d) max=%RX32 (%%%d) calc avg=%RX32 [test=%d]\n",
93 iMin, (iAvg - iMin) * 100 / iAvg, iMax,
94 (iMax - iAvg) * 100 / iAvg,
95 iAvg,
96 iTest);
97 CHECK_EXPR(iMin >= iAvg - iAvg / 4);
98 CHECK_EXPR(iMax <= iAvg + iAvg / 4);
99}
100
101
102static int tstRandAdv(RTRAND hRand)
103{
104 /*
105 * Test distribution.
106 */
107#if 1
108 /* unsigned 32-bit */
109 static const struct
110 {
111 uint32_t u32First;
112 uint32_t u32Last;
113 } s_aU32Tests[] =
114 {
115 { 0, UINT32_MAX },
116 { 0, UINT32_MAX / 2 + UINT32_MAX / 4 },
117 { 0, UINT32_MAX / 2 + UINT32_MAX / 8 },
118 { 0, UINT32_MAX / 2 + UINT32_MAX / 16 },
119 { 0, UINT32_MAX / 2 + UINT32_MAX / 64 },
120 { 0, UINT32_MAX / 2 },
121 { UINT32_MAX / 4, UINT32_MAX / 4 * 3 },
122 { 0, TST_RAND_SAMPLE_RANGES - 1 },
123 { 1234, 1234 + TST_RAND_SAMPLE_RANGES - 1 },
124 };
125 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aU32Tests); iTest++)
126 {
127 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
128 uint32_t const uFirst = s_aU32Tests[iTest].u32First;
129 uint32_t const uLast = s_aU32Tests[iTest].u32Last;
130 uint32_t const uRange = uLast - uFirst; Assert(uLast >= uFirst);
131 uint32_t const uDivisor = uRange / TST_RAND_SAMPLE_RANGES + 1;
132 RTPrintf("tstRand: TESTING RTRandAdvU32Ex(,%#RX32, %#RX32) distribution... [div=%#RX32 range=%#RX32]\n", uFirst, uLast, uDivisor, uRange);
133 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
134 {
135 uint32_t uRand = RTRandAdvU32Ex(hRand, uFirst, uLast);
136 CHECK_EXPR_MSG(uRand >= uFirst, ("%#RX32 %#RX32\n", uRand, uFirst));
137 CHECK_EXPR_MSG(uRand <= uLast, ("%#RX32 %#RX32\n", uRand, uLast));
138 uint32_t off = uRand - uFirst;
139 acHits[off / uDivisor]++;
140 }
141 tstRandCheckDist(acHits, iTest);
142 }
143#endif
144
145#if 1
146 /* unsigned 64-bit */
147 static const struct
148 {
149 uint64_t u64First;
150 uint64_t u64Last;
151 } s_aU64Tests[] =
152 {
153 { 0, UINT64_MAX },
154 { 0, UINT64_MAX / 2 + UINT64_MAX / 4 },
155 { 0, UINT64_MAX / 2 + UINT64_MAX / 8 },
156 { 0, UINT64_MAX / 2 + UINT64_MAX / 16 },
157 { 0, UINT64_MAX / 2 + UINT64_MAX / 64 },
158 { 0, UINT64_MAX / 2 },
159 { UINT64_MAX / 4, UINT64_MAX / 4 * 3 },
160 { 0, UINT32_MAX },
161 { 0, UINT32_MAX / 2 + UINT32_MAX / 4 },
162 { 0, UINT32_MAX / 2 + UINT32_MAX / 8 },
163 { 0, UINT32_MAX / 2 + UINT32_MAX / 16 },
164 { 0, UINT32_MAX / 2 + UINT32_MAX / 64 },
165 { 0, UINT32_MAX / 2 },
166 { UINT32_MAX / 4, UINT32_MAX / 4 * 3 },
167 { 0, TST_RAND_SAMPLE_RANGES - 1 },
168 { 1234, 1234 + TST_RAND_SAMPLE_RANGES - 1 },
169 };
170 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aU64Tests); iTest++)
171 {
172 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
173 uint64_t const uFirst = s_aU64Tests[iTest].u64First;
174 uint64_t const uLast = s_aU64Tests[iTest].u64Last;
175 uint64_t const uRange = uLast - uFirst; Assert(uLast >= uFirst);
176 uint64_t const uDivisor = uRange / TST_RAND_SAMPLE_RANGES + 1;
177 RTPrintf("tstRand: TESTING RTRandAdvU64Ex(,%#RX64, %#RX64) distribution... [div=%#RX64 range=%#RX64]\n", uFirst, uLast, uDivisor, uRange);
178 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
179 {
180 uint64_t uRand = RTRandAdvU64Ex(hRand, uFirst, uLast);
181 CHECK_EXPR_MSG(uRand >= uFirst, ("%#RX64 %#RX64\n", uRand, uFirst));
182 CHECK_EXPR_MSG(uRand <= uLast, ("%#RX64 %#RX64\n", uRand, uLast));
183 uint64_t off = uRand - uFirst;
184 acHits[off / uDivisor]++;
185 }
186 tstRandCheckDist(acHits, iTest);
187 }
188#endif
189
190#if 1
191 /* signed 32-bit */
192 static const struct
193 {
194 int32_t i32First;
195 int32_t i32Last;
196 } s_aS32Tests[] =
197 {
198 { -429496729, 429496729 },
199 { INT32_MIN, INT32_MAX },
200 { INT32_MIN, INT32_MAX / 2 },
201 { -0x20000000, INT32_MAX },
202 { -0x10000000, INT32_MAX },
203 { -0x08000000, INT32_MAX },
204 { -0x00800000, INT32_MAX },
205 { -0x00080000, INT32_MAX },
206 { -0x00008000, INT32_MAX },
207 { -0x00000800, INT32_MAX },
208 { 2, INT32_MAX / 2 },
209 { 4000000, INT32_MAX / 2 },
210 { -4000000, INT32_MAX / 2 },
211 { INT32_MIN / 2, INT32_MAX / 2 },
212 { INT32_MIN / 3, INT32_MAX / 2 },
213 { INT32_MIN / 3, INT32_MAX / 3 },
214 { INT32_MIN / 3, INT32_MAX / 4 },
215 { INT32_MIN / 4, INT32_MAX / 4 },
216 { INT32_MIN / 5, INT32_MAX / 5 },
217 { INT32_MIN / 6, INT32_MAX / 6 },
218 { INT32_MIN / 7, INT32_MAX / 6 },
219 { INT32_MIN / 7, INT32_MAX / 7 },
220 { INT32_MIN / 7, INT32_MAX / 8 },
221 { INT32_MIN / 8, INT32_MAX / 8 },
222 { INT32_MIN / 9, INT32_MAX / 9 },
223 { INT32_MIN / 9, INT32_MAX / 12 },
224 { INT32_MIN / 12, INT32_MAX / 12 },
225 { 0, TST_RAND_SAMPLE_RANGES - 1 },
226 { -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 },
227 };
228 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS32Tests); iTest++)
229 {
230 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
231 int32_t const iFirst = s_aS32Tests[iTest].i32First;
232 int32_t const iLast = s_aS32Tests[iTest].i32Last;
233 uint32_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
234 uint32_t const uDivisor = (uRange ? uRange : UINT32_MAX) / TST_RAND_SAMPLE_RANGES + 1;
235 RTPrintf("tstRand: TESTING RTRandAdvS32Ex(,%#RI32, %#RI32) distribution... [div=%#RX32 range=%#RX32]\n", iFirst, iLast, uDivisor, uRange);
236 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
237 {
238 int32_t iRand = RTRandAdvS32Ex(hRand, iFirst, iLast);
239 CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI32 %#RI32\n", iRand, iFirst));
240 CHECK_EXPR_MSG(iRand <= iLast, ("%#RI32 %#RI32\n", iRand, iLast));
241 uint32_t off = iRand - iFirst;
242 acHits[off / uDivisor]++;
243 }
244 tstRandCheckDist(acHits, iTest);
245 }
246#endif
247
248#if 1
249 /* signed 64-bit */
250 static const struct
251 {
252 int64_t i64First;
253 int64_t i64Last;
254 } s_aS64Tests[] =
255 {
256 { INT64_MIN, INT64_MAX },
257 { INT64_MIN, INT64_MAX / 2 },
258 { INT64_MIN / 2, INT64_MAX / 2 },
259 { INT64_MIN / 2 + INT64_MIN / 4, INT64_MAX / 2 },
260 { INT64_MIN / 2 + INT64_MIN / 8, INT64_MAX / 2 },
261 { INT64_MIN / 2 + INT64_MIN / 16, INT64_MAX / 2 },
262 { INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 },
263 { INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 + INT64_MAX / 64 },
264 { INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 64 },
265 { INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 8 },
266 { INT64_MIN / 2, INT64_MAX / 2 - INT64_MAX / 8 },
267 { INT64_MIN / 2 - INT64_MIN / 4, INT64_MAX / 2 - INT64_MAX / 4 },
268 { INT64_MIN / 2 - INT64_MIN / 4, INT64_MAX / 2 - INT64_MAX / 8 },
269 { INT64_MIN / 2 - INT64_MIN / 8, INT64_MAX / 2 - INT64_MAX / 8 },
270 { INT64_MIN / 2 - INT64_MIN / 16, INT64_MAX / 2 - INT64_MAX / 8 },
271 { INT64_MIN / 2 - INT64_MIN / 16, INT64_MAX / 2 - INT64_MAX / 16 },
272 { INT64_MIN / 2 - INT64_MIN / 32, INT64_MAX / 2 - INT64_MAX / 16 },
273 { INT64_MIN / 2 - INT64_MIN / 32, INT64_MAX / 2 - INT64_MAX / 32 },
274 { INT64_MIN / 2 - INT64_MIN / 64, INT64_MAX / 2 - INT64_MAX / 64 },
275 { INT64_MIN / 2 - INT64_MIN / 8, INT64_MAX / 2 },
276 { INT64_MIN / 4, INT64_MAX / 4 },
277 { INT64_MIN / 5, INT64_MAX / 5 },
278 { INT64_MIN / 6, INT64_MAX / 6 },
279 { INT64_MIN / 7, INT64_MAX / 7 },
280 { INT64_MIN / 8, INT64_MAX / 8 },
281 { INT32_MIN, INT32_MAX },
282 { INT32_MIN, INT32_MAX / 2 },
283 { -0x20000000, INT32_MAX },
284 { -0x10000000, INT32_MAX },
285 { -0x7f000000, INT32_MAX },
286 { -0x08000000, INT32_MAX },
287 { -0x00800000, INT32_MAX },
288 { -0x00080000, INT32_MAX },
289 { -0x00008000, INT32_MAX },
290 { 2, INT32_MAX / 2 },
291 { 4000000, INT32_MAX / 2 },
292 { -4000000, INT32_MAX / 2 },
293 { INT32_MIN / 2, INT32_MAX / 2 },
294 { 0, TST_RAND_SAMPLE_RANGES - 1 },
295 { -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 }
296 };
297 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS64Tests); iTest++)
298 {
299 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
300 int64_t const iFirst = s_aS64Tests[iTest].i64First;
301 int64_t const iLast = s_aS64Tests[iTest].i64Last;
302 uint64_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
303 uint64_t const uDivisor = (uRange ? uRange : UINT64_MAX) / TST_RAND_SAMPLE_RANGES + 1;
304 RTPrintf("tstRand: TESTING RTRandAdvS64Ex(,%#RI64, %#RI64) distribution... [div=%#RX64 range=%#016RX64]\n", iFirst, iLast, uDivisor, uRange);
305 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
306 {
307 int64_t iRand = RTRandAdvS64Ex(hRand, iFirst, iLast);
308 CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI64 %#RI64\n", iRand, iFirst));
309 CHECK_EXPR_MSG(iRand <= iLast, ("%#RI64 %#RI64\n", iRand, iLast));
310 uint64_t off = iRand - iFirst;
311 acHits[off / uDivisor]++;
312 }
313 tstRandCheckDist(acHits, iTest);
314 }
315#endif
316
317 /*
318 * Test saving and restoring the state.
319 */
320 RTPrintf("tstRand: TESTING RTRandAdvSave/RestoreSave\n");
321 char szState[256];
322 size_t cbState = sizeof(szState);
323 int rc = RTRandAdvSaveState(hRand, szState, &cbState);
324 if (rc != VERR_NOT_SUPPORTED)
325 {
326 CHECK_EXPR_MSG(rc == VINF_SUCCESS, ("RTRandAdvSaveState(%p,,256) -> %Rrc (%d)\n", (uintptr_t)hRand, rc, rc));
327 uint32_t const u32A1 = RTRandAdvU32(hRand);
328 uint32_t const u32B1 = RTRandAdvU32(hRand);
329 RTPrintf("tstRand: state:\"%s\" A=%RX32 B=%RX32\n", szState, u32A1, u32B1);
330
331 rc = RTRandAdvRestoreState(hRand, szState);
332 CHECK_EXPR_MSG(rc == VINF_SUCCESS, ("RTRandAdvRestoreState(%p,\"%s\") -> %Rrc (%d)\n", (uintptr_t)hRand, szState, rc, rc));
333 uint32_t const u32A2 = RTRandAdvU32(hRand);
334 uint32_t const u32B2 = RTRandAdvU32(hRand);
335 CHECK_EXPR_MSG(u32A1 == u32A2, ("u32A1=%RX32 u32A2=%RX32\n", u32A1, u32A2));
336 CHECK_EXPR_MSG(u32B1 == u32B2, ("u32B1=%RX32 u32B2=%RX32\n", u32B1, u32B2));
337 }
338 else
339 {
340 szState[0] = '\0';
341 rc = RTRandAdvRestoreState(hRand, szState);
342 CHECK_EXPR_MSG(rc == VERR_NOT_SUPPORTED, ("RTRandAdvRestoreState(%p,\"\") -> %Rrc (%d)\n", (uintptr_t)hRand, rc, rc));
343 }
344
345
346 /*
347 * Destroy it.
348 */
349 rc = RTRandAdvDestroy(hRand);
350 CHECK_EXPR_MSG(rc == VINF_SUCCESS, ("RTRandAdvDestroy(%p) -> %Rrc (%d)\n", (uintptr_t)hRand, rc, rc));
351
352 return 0;
353}
354
355
356
357int main()
358{
359 RTR3InitExeNoArguments(0);
360 RTPrintf("tstRand: TESTING...\n");
361
362 /*
363 * Do some smoke tests first?
364 */
365 /** @todo RTRand smoke testing. */
366
367#if 1
368 /*
369 * Test distribution.
370 */
371#if 1
372 /* unsigned 32-bit */
373 static const struct
374 {
375 uint32_t u32First;
376 uint32_t u32Last;
377 } s_aU32Tests[] =
378 {
379 { 0, UINT32_MAX },
380 { 0, UINT32_MAX / 2 + UINT32_MAX / 4 },
381 { 0, UINT32_MAX / 2 + UINT32_MAX / 8 },
382 { 0, UINT32_MAX / 2 + UINT32_MAX / 16 },
383 { 0, UINT32_MAX / 2 + UINT32_MAX / 64 },
384 { 0, UINT32_MAX / 2 },
385 { UINT32_MAX / 4, UINT32_MAX / 4 * 3 },
386 { 0, TST_RAND_SAMPLE_RANGES - 1 },
387 { 1234, 1234 + TST_RAND_SAMPLE_RANGES - 1 },
388 };
389 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aU32Tests); iTest++)
390 {
391 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
392 uint32_t const uFirst = s_aU32Tests[iTest].u32First;
393 uint32_t const uLast = s_aU32Tests[iTest].u32Last;
394 uint32_t const uRange = uLast - uFirst; Assert(uLast >= uFirst);
395 uint32_t const uDivisor = uRange / TST_RAND_SAMPLE_RANGES + 1;
396 RTPrintf("tstRand: TESTING RTRandU32Ex(%#RX32, %#RX32) distribution... [div=%#RX32 range=%#RX32]\n", uFirst, uLast, uDivisor, uRange);
397 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
398 {
399 uint32_t uRand = RTRandU32Ex(uFirst, uLast);
400 CHECK_EXPR_MSG(uRand >= uFirst, ("%#RX32 %#RX32\n", uRand, uFirst));
401 CHECK_EXPR_MSG(uRand <= uLast, ("%#RX32 %#RX32\n", uRand, uLast));
402 uint32_t off = uRand - uFirst;
403 acHits[off / uDivisor]++;
404 }
405 tstRandCheckDist(acHits, iTest);
406 }
407#endif
408
409#if 1
410 /* unsigned 64-bit */
411 static const struct
412 {
413 uint64_t u64First;
414 uint64_t u64Last;
415 } s_aU64Tests[] =
416 {
417 { 0, UINT64_MAX },
418 { 0, UINT64_MAX / 2 + UINT64_MAX / 4 },
419 { 0, UINT64_MAX / 2 + UINT64_MAX / 8 },
420 { 0, UINT64_MAX / 2 + UINT64_MAX / 16 },
421 { 0, UINT64_MAX / 2 + UINT64_MAX / 64 },
422 { 0, UINT64_MAX / 2 },
423 { UINT64_MAX / 4, UINT64_MAX / 4 * 3 },
424 { 0, UINT32_MAX },
425 { 0, UINT32_MAX / 2 + UINT32_MAX / 4 },
426 { 0, UINT32_MAX / 2 + UINT32_MAX / 8 },
427 { 0, UINT32_MAX / 2 + UINT32_MAX / 16 },
428 { 0, UINT32_MAX / 2 + UINT32_MAX / 64 },
429 { 0, UINT32_MAX / 2 },
430 { UINT32_MAX / 4, UINT32_MAX / 4 * 3 },
431 { 0, TST_RAND_SAMPLE_RANGES - 1 },
432 { 1234, 1234 + TST_RAND_SAMPLE_RANGES - 1 },
433 };
434 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aU64Tests); iTest++)
435 {
436 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
437 uint64_t const uFirst = s_aU64Tests[iTest].u64First;
438 uint64_t const uLast = s_aU64Tests[iTest].u64Last;
439 uint64_t const uRange = uLast - uFirst; Assert(uLast >= uFirst);
440 uint64_t const uDivisor = uRange / TST_RAND_SAMPLE_RANGES + 1;
441 RTPrintf("tstRand: TESTING RTRandU64Ex(%#RX64, %#RX64) distribution... [div=%#RX64 range=%#RX64]\n", uFirst, uLast, uDivisor, uRange);
442 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
443 {
444 uint64_t uRand = RTRandU64Ex(uFirst, uLast);
445 CHECK_EXPR_MSG(uRand >= uFirst, ("%#RX64 %#RX64\n", uRand, uFirst));
446 CHECK_EXPR_MSG(uRand <= uLast, ("%#RX64 %#RX64\n", uRand, uLast));
447 uint64_t off = uRand - uFirst;
448 acHits[off / uDivisor]++;
449 }
450 tstRandCheckDist(acHits, iTest);
451 }
452#endif
453
454#if 1
455 /* signed 32-bit */
456 static const struct
457 {
458 int32_t i32First;
459 int32_t i32Last;
460 } s_aS32Tests[] =
461 {
462 { -429496729, 429496729 },
463 { INT32_MIN, INT32_MAX },
464 { INT32_MIN, INT32_MAX / 2 },
465 { -0x20000000, INT32_MAX },
466 { -0x10000000, INT32_MAX },
467 { -0x08000000, INT32_MAX },
468 { -0x00800000, INT32_MAX },
469 { -0x00080000, INT32_MAX },
470 { -0x00008000, INT32_MAX },
471 { -0x00000800, INT32_MAX },
472 { 2, INT32_MAX / 2 },
473 { 4000000, INT32_MAX / 2 },
474 { -4000000, INT32_MAX / 2 },
475 { INT32_MIN / 2, INT32_MAX / 2 },
476 { INT32_MIN / 3, INT32_MAX / 2 },
477 { INT32_MIN / 3, INT32_MAX / 3 },
478 { INT32_MIN / 3, INT32_MAX / 4 },
479 { INT32_MIN / 4, INT32_MAX / 4 },
480 { INT32_MIN / 5, INT32_MAX / 5 },
481 { INT32_MIN / 6, INT32_MAX / 6 },
482 { INT32_MIN / 7, INT32_MAX / 6 },
483 { INT32_MIN / 7, INT32_MAX / 7 },
484 { INT32_MIN / 7, INT32_MAX / 8 },
485 { INT32_MIN / 8, INT32_MAX / 8 },
486 { INT32_MIN / 9, INT32_MAX / 9 },
487 { INT32_MIN / 9, INT32_MAX / 12 },
488 { INT32_MIN / 12, INT32_MAX / 12 },
489 { 0, TST_RAND_SAMPLE_RANGES - 1 },
490 { -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 },
491 };
492 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS32Tests); iTest++)
493 {
494 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
495 int32_t const iFirst = s_aS32Tests[iTest].i32First;
496 int32_t const iLast = s_aS32Tests[iTest].i32Last;
497 uint32_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
498 uint32_t const uDivisor = (uRange ? uRange : UINT32_MAX) / TST_RAND_SAMPLE_RANGES + 1;
499 RTPrintf("tstRand: TESTING RTRandS32Ex(%#RI32, %#RI32) distribution... [div=%#RX32 range=%#RX32]\n", iFirst, iLast, uDivisor, uRange);
500 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
501 {
502 int32_t iRand = RTRandS32Ex(iFirst, iLast);
503 CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI32 %#RI32\n", iRand, iFirst));
504 CHECK_EXPR_MSG(iRand <= iLast, ("%#RI32 %#RI32\n", iRand, iLast));
505 uint32_t off = iRand - iFirst;
506 acHits[off / uDivisor]++;
507 }
508 tstRandCheckDist(acHits, iTest);
509 }
510#endif
511
512#if 1
513 /* signed 64-bit */
514 static const struct
515 {
516 int64_t i64First;
517 int64_t i64Last;
518 } s_aS64Tests[] =
519 {
520 { INT64_MIN, INT64_MAX },
521 { INT64_MIN, INT64_MAX / 2 },
522 { INT64_MIN / 2, INT64_MAX / 2 },
523 { INT64_MIN / 2 + INT64_MIN / 4, INT64_MAX / 2 },
524 { INT64_MIN / 2 + INT64_MIN / 8, INT64_MAX / 2 },
525 { INT64_MIN / 2 + INT64_MIN / 16, INT64_MAX / 2 },
526 { INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 },
527 { INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 + INT64_MAX / 64 },
528 { INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 64 },
529 { INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 8 },
530 { INT64_MIN / 2, INT64_MAX / 2 - INT64_MAX / 8 },
531 { INT64_MIN / 2 - INT64_MIN / 4, INT64_MAX / 2 - INT64_MAX / 4 },
532 { INT64_MIN / 2 - INT64_MIN / 4, INT64_MAX / 2 - INT64_MAX / 8 },
533 { INT64_MIN / 2 - INT64_MIN / 8, INT64_MAX / 2 - INT64_MAX / 8 },
534 { INT64_MIN / 2 - INT64_MIN / 16, INT64_MAX / 2 - INT64_MAX / 8 },
535 { INT64_MIN / 2 - INT64_MIN / 16, INT64_MAX / 2 - INT64_MAX / 16 },
536 { INT64_MIN / 2 - INT64_MIN / 32, INT64_MAX / 2 - INT64_MAX / 16 },
537 { INT64_MIN / 2 - INT64_MIN / 32, INT64_MAX / 2 - INT64_MAX / 32 },
538 { INT64_MIN / 2 - INT64_MIN / 64, INT64_MAX / 2 - INT64_MAX / 64 },
539 { INT64_MIN / 2 - INT64_MIN / 8, INT64_MAX / 2 },
540 { INT64_MIN / 4, INT64_MAX / 4 },
541 { INT64_MIN / 5, INT64_MAX / 5 },
542 { INT64_MIN / 6, INT64_MAX / 6 },
543 { INT64_MIN / 7, INT64_MAX / 7 },
544 { INT64_MIN / 8, INT64_MAX / 8 },
545 { INT32_MIN, INT32_MAX },
546 { INT32_MIN, INT32_MAX / 2 },
547 { -0x20000000, INT32_MAX },
548 { -0x10000000, INT32_MAX },
549 { -0x7f000000, INT32_MAX },
550 { -0x08000000, INT32_MAX },
551 { -0x00800000, INT32_MAX },
552 { -0x00080000, INT32_MAX },
553 { -0x00008000, INT32_MAX },
554 { 2, INT32_MAX / 2 },
555 { 4000000, INT32_MAX / 2 },
556 { -4000000, INT32_MAX / 2 },
557 { INT32_MIN / 2, INT32_MAX / 2 },
558 { 0, TST_RAND_SAMPLE_RANGES - 1 },
559 { -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 }
560 };
561 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS64Tests); iTest++)
562 {
563 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
564 int64_t const iFirst = s_aS64Tests[iTest].i64First;
565 int64_t const iLast = s_aS64Tests[iTest].i64Last;
566 uint64_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
567 uint64_t const uDivisor = (uRange ? uRange : UINT64_MAX) / TST_RAND_SAMPLE_RANGES + 1;
568 RTPrintf("tstRand: TESTING RTRandS64Ex(%#RI64, %#RI64) distribution... [div=%#RX64 range=%#016RX64]\n", iFirst, iLast, uDivisor, uRange);
569 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
570 {
571 int64_t iRand = RTRandS64Ex(iFirst, iLast);
572 CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI64 %#RI64\n", iRand, iFirst));
573 CHECK_EXPR_MSG(iRand <= iLast, ("%#RI64 %#RI64\n", iRand, iLast));
574 uint64_t off = iRand - iFirst;
575 acHits[off / uDivisor]++;
576 }
577 tstRandCheckDist(acHits, iTest);
578 }
579#endif
580#endif /* Testing RTRand */
581
582#if 1
583 /*
584 * Test the various random generators.
585 */
586 RTPrintf("tstRand: TESTING RTRandAdvCreateParkerMiller\n");
587 RTRAND hRand;
588 int rc = RTRandAdvCreateParkMiller(&hRand);
589 CHECK_EXPR_MSG(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc));
590 if (RT_SUCCESS(rc))
591 if (tstRandAdv(hRand))
592 return 1;
593
594#endif /* Testing RTRandAdv */
595
596 /*
597 * Summary.
598 */
599 if (!g_cErrors)
600 RTPrintf("tstRand: SUCCESS\n");
601 else
602 RTPrintf("tstRand: FAILED - %d errors\n", g_cErrors);
603 return !!g_cErrors;
604}
605
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use