1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #include "./blapi-build_p.h" |
8 | #include "./blrandom_p.h" |
9 | #include "./blsimd_p.h" |
10 | |
11 | // ============================================================================ |
12 | // [BLRandom - Core] |
13 | // ============================================================================ |
14 | |
15 | void blRandomReset(BLRandom* self, uint64_t seed) noexcept { blRandomResetInline(self, seed); } |
16 | double blRandomNextDouble(BLRandom* self) noexcept { return blRandomNextDoubleInline(self); } |
17 | uint32_t blRandomNextUInt32(BLRandom* self) noexcept { return blRandomNextUInt32Inline(self); } |
18 | uint64_t blRandomNextUInt64(BLRandom* self) noexcept { return blRandomNextUInt64Inline(self); } |
19 | |
20 | // ============================================================================ |
21 | // [BLRandom - Unit Tests] |
22 | // ============================================================================ |
23 | |
24 | #ifdef BL_TEST |
25 | UNIT(blend2d_random) { |
26 | // Number of iterations for tests that use loop. |
27 | enum { kCount = 1000000 }; |
28 | |
29 | // Test whether the SIMD implementation matches the C++ one. |
30 | #if defined(BL_TARGET_OPT_SSE2) |
31 | { |
32 | BLRandom a(0); |
33 | BLRandom b(0); |
34 | |
35 | SIMD::I128 bLo = blRandomNextUInt64AsI128Inline(&b); |
36 | SIMD::I128 bHi = SIMD::vswizi32<2, 3, 0, 1>(bLo); |
37 | |
38 | uint64_t aVal = a.nextUInt64(); |
39 | uint64_t bVal = (uint64_t(SIMD::vcvti128i32(bLo)) ) + |
40 | (uint64_t(SIMD::vcvti128i32(bHi)) << 32) ; |
41 | |
42 | EXPECT(aVal == bVal); |
43 | } |
44 | #endif |
45 | |
46 | // Test whether the random 32-bit integer is the HI part of the 64-bit one. |
47 | { |
48 | BLRandom a(0); |
49 | BLRandom b(0); |
50 | EXPECT(uint32_t(a.nextUInt64() >> 32) == b.nextUInt32()); |
51 | } |
52 | |
53 | // Test whether returned doubles satisfy [0..1) condition. |
54 | { |
55 | // Supply a low-entropy seed on purpose. |
56 | BLRandom rnd(3); |
57 | |
58 | uint32_t below = 0; |
59 | uint32_t above = 0; |
60 | |
61 | for (uint32_t i = 0; i < kCount; i++) { |
62 | double x = rnd.nextDouble(); |
63 | below += x < 0.5; |
64 | above += x >= 0.5; |
65 | EXPECT(x >= 0.0 && x < 1.0); |
66 | } |
67 | INFO("Random numbers at [0.0, 0.5): %u of %u" , below, kCount); |
68 | INFO("Random numbers at [0.5, 1.0): %u of %u" , above, kCount); |
69 | } |
70 | } |
71 | #endif |
72 | |