VirtualBox

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

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

iprt/rand: Added a generic RTRandAdv API for use with any random number generator. Implemented the classic Park-Miller pseudo random number generator.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.5 KB
Line 
1/* $Id: tstRand.cpp 11347 2008-08-11 21:12:55Z 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 { -0x080000000, INT32_MAX },
205 { -0x008000000, INT32_MAX },
206 { -0x000800000, INT32_MAX },
207 { -0x000080000, INT32_MAX },
208 { -0x000008000, 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 * Destroy it.
320 */
321 int rc = RTRandAdvDestroy(hRand);
322 CHECK_EXPR_MSG(rc == VINF_SUCCESS, ("RTRandAdvDestroy(%p) -> %Rrc (%d)\n", (uintptr_t)hRand, rc, rc));
323
324 return 0;
325}
326
327
328
329int main()
330{
331 RTR3Init(false);
332 RTPrintf("tstRand: TESTING...\n");
333
334 /*
335 * Do some smoke tests first?
336 */
337 /** @todo RTRand smoke testing. */
338
339#if 1
340 /*
341 * Test distribution.
342 */
343#if 1
344 /* unsigned 32-bit */
345 static const struct
346 {
347 uint32_t u32First;
348 uint32_t u32Last;
349 } s_aU32Tests[] =
350 {
351 { 0, UINT32_MAX },
352 { 0, UINT32_MAX / 2 + UINT32_MAX / 4 },
353 { 0, UINT32_MAX / 2 + UINT32_MAX / 8 },
354 { 0, UINT32_MAX / 2 + UINT32_MAX / 16 },
355 { 0, UINT32_MAX / 2 + UINT32_MAX / 64 },
356 { 0, UINT32_MAX / 2 },
357 { UINT32_MAX / 4, UINT32_MAX / 4 * 3 },
358 { 0, TST_RAND_SAMPLE_RANGES - 1 },
359 { 1234, 1234 + TST_RAND_SAMPLE_RANGES - 1 },
360 };
361 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aU32Tests); iTest++)
362 {
363 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
364 uint32_t const uFirst = s_aU32Tests[iTest].u32First;
365 uint32_t const uLast = s_aU32Tests[iTest].u32Last;
366 uint32_t const uRange = uLast - uFirst; Assert(uLast >= uFirst);
367 uint32_t const uDivisor = uRange / TST_RAND_SAMPLE_RANGES + 1;
368 RTPrintf("tstRand: TESTING RTRandU32Ex(%#RX32, %#RX32) distribution... [div=%#RX32 range=%#RX32]\n", uFirst, uLast, uDivisor, uRange);
369 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
370 {
371 uint32_t uRand = RTRandU32Ex(uFirst, uLast);
372 CHECK_EXPR_MSG(uRand >= uFirst, ("%#RX32 %#RX32\n", uRand, uFirst));
373 CHECK_EXPR_MSG(uRand <= uLast, ("%#RX32 %#RX32\n", uRand, uLast));
374 uint32_t off = uRand - uFirst;
375 acHits[off / uDivisor]++;
376 }
377 tstRandCheckDist(acHits, iTest);
378 }
379#endif
380
381#if 1
382 /* unsigned 64-bit */
383 static const struct
384 {
385 uint64_t u64First;
386 uint64_t u64Last;
387 } s_aU64Tests[] =
388 {
389 { 0, UINT64_MAX },
390 { 0, UINT64_MAX / 2 + UINT64_MAX / 4 },
391 { 0, UINT64_MAX / 2 + UINT64_MAX / 8 },
392 { 0, UINT64_MAX / 2 + UINT64_MAX / 16 },
393 { 0, UINT64_MAX / 2 + UINT64_MAX / 64 },
394 { 0, UINT64_MAX / 2 },
395 { UINT64_MAX / 4, UINT64_MAX / 4 * 3 },
396 { 0, UINT32_MAX },
397 { 0, UINT32_MAX / 2 + UINT32_MAX / 4 },
398 { 0, UINT32_MAX / 2 + UINT32_MAX / 8 },
399 { 0, UINT32_MAX / 2 + UINT32_MAX / 16 },
400 { 0, UINT32_MAX / 2 + UINT32_MAX / 64 },
401 { 0, UINT32_MAX / 2 },
402 { UINT32_MAX / 4, UINT32_MAX / 4 * 3 },
403 { 0, TST_RAND_SAMPLE_RANGES - 1 },
404 { 1234, 1234 + TST_RAND_SAMPLE_RANGES - 1 },
405 };
406 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aU64Tests); iTest++)
407 {
408 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
409 uint64_t const uFirst = s_aU64Tests[iTest].u64First;
410 uint64_t const uLast = s_aU64Tests[iTest].u64Last;
411 uint64_t const uRange = uLast - uFirst; Assert(uLast >= uFirst);
412 uint64_t const uDivisor = uRange / TST_RAND_SAMPLE_RANGES + 1;
413 RTPrintf("tstRand: TESTING RTRandU64Ex(%#RX64, %#RX64) distribution... [div=%#RX64 range=%#RX64]\n", uFirst, uLast, uDivisor, uRange);
414 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
415 {
416 uint64_t uRand = RTRandU64Ex(uFirst, uLast);
417 CHECK_EXPR_MSG(uRand >= uFirst, ("%#RX64 %#RX64\n", uRand, uFirst));
418 CHECK_EXPR_MSG(uRand <= uLast, ("%#RX64 %#RX64\n", uRand, uLast));
419 uint64_t off = uRand - uFirst;
420 acHits[off / uDivisor]++;
421 }
422 tstRandCheckDist(acHits, iTest);
423 }
424#endif
425
426#if 1
427 /* signed 32-bit */
428 static const struct
429 {
430 int32_t i32First;
431 int32_t i32Last;
432 } s_aS32Tests[] =
433 {
434 { -429496729, 429496729 },
435 { INT32_MIN, INT32_MAX },
436 { INT32_MIN, INT32_MAX / 2 },
437 { -0x20000000, INT32_MAX },
438 { -0x10000000, INT32_MAX },
439 { -0x080000000, INT32_MAX },
440 { -0x008000000, INT32_MAX },
441 { -0x000800000, INT32_MAX },
442 { -0x000080000, INT32_MAX },
443 { -0x000008000, INT32_MAX },
444 { 2, INT32_MAX / 2 },
445 { 4000000, INT32_MAX / 2 },
446 { -4000000, INT32_MAX / 2 },
447 { INT32_MIN / 2, INT32_MAX / 2 },
448 { INT32_MIN / 3, INT32_MAX / 2 },
449 { INT32_MIN / 3, INT32_MAX / 3 },
450 { INT32_MIN / 3, INT32_MAX / 4 },
451 { INT32_MIN / 4, INT32_MAX / 4 },
452 { INT32_MIN / 5, INT32_MAX / 5 },
453 { INT32_MIN / 6, INT32_MAX / 6 },
454 { INT32_MIN / 7, INT32_MAX / 6 },
455 { INT32_MIN / 7, INT32_MAX / 7 },
456 { INT32_MIN / 7, INT32_MAX / 8 },
457 { INT32_MIN / 8, INT32_MAX / 8 },
458 { INT32_MIN / 9, INT32_MAX / 9 },
459 { INT32_MIN / 9, INT32_MAX / 12 },
460 { INT32_MIN / 12, INT32_MAX / 12 },
461 { 0, TST_RAND_SAMPLE_RANGES - 1 },
462 { -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 },
463 };
464 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS32Tests); iTest++)
465 {
466 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
467 int32_t const iFirst = s_aS32Tests[iTest].i32First;
468 int32_t const iLast = s_aS32Tests[iTest].i32Last;
469 uint32_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
470 uint32_t const uDivisor = (uRange ? uRange : UINT32_MAX) / TST_RAND_SAMPLE_RANGES + 1;
471 RTPrintf("tstRand: TESTING RTRandS32Ex(%#RI32, %#RI32) distribution... [div=%#RX32 range=%#RX32]\n", iFirst, iLast, uDivisor, uRange);
472 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
473 {
474 int32_t iRand = RTRandS32Ex(iFirst, iLast);
475 CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI32 %#RI32\n", iRand, iFirst));
476 CHECK_EXPR_MSG(iRand <= iLast, ("%#RI32 %#RI32\n", iRand, iLast));
477 uint32_t off = iRand - iFirst;
478 acHits[off / uDivisor]++;
479 }
480 tstRandCheckDist(acHits, iTest);
481 }
482#endif
483
484#if 1
485 /* signed 64-bit */
486 static const struct
487 {
488 int64_t i64First;
489 int64_t i64Last;
490 } s_aS64Tests[] =
491 {
492 { INT64_MIN, INT64_MAX },
493 { INT64_MIN, INT64_MAX / 2 },
494 { INT64_MIN / 2, INT64_MAX / 2 },
495 { INT64_MIN / 2 + INT64_MIN / 4, INT64_MAX / 2 },
496 { INT64_MIN / 2 + INT64_MIN / 8, INT64_MAX / 2 },
497 { INT64_MIN / 2 + INT64_MIN / 16, INT64_MAX / 2 },
498 { INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 },
499 { INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 + INT64_MAX / 64 },
500 { INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 64 },
501 { INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 8 },
502 { INT64_MIN / 2, INT64_MAX / 2 - INT64_MAX / 8 },
503 { INT64_MIN / 2 - INT64_MIN / 4, INT64_MAX / 2 - INT64_MAX / 4 },
504 { INT64_MIN / 2 - INT64_MIN / 4, INT64_MAX / 2 - INT64_MAX / 8 },
505 { INT64_MIN / 2 - INT64_MIN / 8, INT64_MAX / 2 - INT64_MAX / 8 },
506 { INT64_MIN / 2 - INT64_MIN / 16, INT64_MAX / 2 - INT64_MAX / 8 },
507 { INT64_MIN / 2 - INT64_MIN / 16, INT64_MAX / 2 - INT64_MAX / 16 },
508 { INT64_MIN / 2 - INT64_MIN / 32, INT64_MAX / 2 - INT64_MAX / 16 },
509 { INT64_MIN / 2 - INT64_MIN / 32, INT64_MAX / 2 - INT64_MAX / 32 },
510 { INT64_MIN / 2 - INT64_MIN / 64, INT64_MAX / 2 - INT64_MAX / 64 },
511 { INT64_MIN / 2 - INT64_MIN / 8, INT64_MAX / 2 },
512 { INT64_MIN / 4, INT64_MAX / 4 },
513 { INT64_MIN / 5, INT64_MAX / 5 },
514 { INT64_MIN / 6, INT64_MAX / 6 },
515 { INT64_MIN / 7, INT64_MAX / 7 },
516 { INT64_MIN / 8, INT64_MAX / 8 },
517 { INT32_MIN, INT32_MAX },
518 { INT32_MIN, INT32_MAX / 2 },
519 { -0x20000000, INT32_MAX },
520 { -0x10000000, INT32_MAX },
521 { -0x7f000000, INT32_MAX },
522 { -0x08000000, INT32_MAX },
523 { -0x00800000, INT32_MAX },
524 { -0x00080000, INT32_MAX },
525 { -0x00008000, INT32_MAX },
526 { 2, INT32_MAX / 2 },
527 { 4000000, INT32_MAX / 2 },
528 { -4000000, INT32_MAX / 2 },
529 { INT32_MIN / 2, INT32_MAX / 2 },
530 { 0, TST_RAND_SAMPLE_RANGES - 1 },
531 { -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 }
532 };
533 for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS64Tests); iTest++)
534 {
535 uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
536 int64_t const iFirst = s_aS64Tests[iTest].i64First;
537 int64_t const iLast = s_aS64Tests[iTest].i64Last;
538 uint64_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
539 uint64_t const uDivisor = (uRange ? uRange : UINT64_MAX) / TST_RAND_SAMPLE_RANGES + 1;
540 RTPrintf("tstRand: TESTING RTRandS64Ex(%#RI64, %#RI64) distribution... [div=%#RX64 range=%#016RX64]\n", iFirst, iLast, uDivisor, uRange);
541 for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
542 {
543 int64_t iRand = RTRandS64Ex(iFirst, iLast);
544 CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI64 %#RI64\n", iRand, iFirst));
545 CHECK_EXPR_MSG(iRand <= iLast, ("%#RI64 %#RI64\n", iRand, iLast));
546 uint64_t off = iRand - iFirst;
547 acHits[off / uDivisor]++;
548 }
549 tstRandCheckDist(acHits, iTest);
550 }
551#endif
552#endif /* Testing RTRand */
553
554#if 1
555 /*
556 * Test the various random generators.
557 */
558 RTPrintf("tstRand: TESTING RTRandAdvCreateParkerMiller\n");
559 RTRAND hRand;
560 int rc = RTRandAdvCreateParkMiller(&hRand);
561 CHECK_EXPR_MSG(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc));
562 if (RT_SUCCESS(rc))
563 if (tstRandAdv(hRand))
564 return 1;
565
566#endif /* Testing RTRandAdv */
567
568 /*
569 * Summary.
570 */
571 if (!g_cErrors)
572 RTPrintf("tstRand: SUCCESS\n");
573 else
574 RTPrintf("tstRand: FAILED - %d errors\n", g_cErrors);
575 return !!g_cErrors;
576}
577
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