VirtualBox

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

Last change on this file since 39091 was 38636, checked in by vboxsync, 13 years ago

*,IPRT: Redid the ring-3 init to always convert the arguments to UTF-8.

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