VirtualBox

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

Last change on this file since 20606 was 18455, checked in by vboxsync, 16 years ago

tstRand: fixed warning stemming from a row of extra zeros.

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