VirtualBox

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

Last change on this file since 73705 was 69111, checked in by vboxsync, 7 years ago

(C) year

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