VirtualBox

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

Last change on this file since 106579 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

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