xref: /llvm-project/libcxx/test/std/numerics/rand/rand.util/rand.util.canonical/generate_canonical.pass.cpp (revision c310e5a7ab6c7606f2c9ef0d7b0efae8a5568efe)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <random>
10 
11 // template<class RealType, size_t bits, class URNG>
12 //     RealType generate_canonical(URNG& g);
13 
14 #include <random>
15 #include <cassert>
16 
17 #include "test_macros.h"
18 #include "truncate_fp.h"
19 
20 int main(int, char**)
21 {
22     typedef std::minstd_rand0 E;
23     auto range = E::max() - E::min();
24 
25     {
26         typedef float F;
27         E r;
28         F f = std::generate_canonical<F, 0>(r);
29         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
30     }
31     {
32         typedef float F;
33         E r;
34         F f = std::generate_canonical<F, 1>(r);
35         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
36     }
37     {
38         typedef float F;
39         E r;
40         F f = std::generate_canonical<F, std::numeric_limits<F>::digits - 1>(r);
41         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
42     }
43     {
44         typedef float F;
45         E r;
46         F f = std::generate_canonical<F, std::numeric_limits<F>::digits>(r);
47         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
48     }
49     {
50         typedef float F;
51         E r;
52         F f = std::generate_canonical<F, std::numeric_limits<F>::digits + 1>(r);
53         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
54     }
55 
56     {
57         typedef double F;
58         E r;
59         F f = std::generate_canonical<F, 0>(r);
60         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
61     }
62     {
63         typedef double F;
64         E r;
65         F f = std::generate_canonical<F, 1>(r);
66         assert(f == truncate_fp((16807 - E::min()) / (range + F(1))));
67     }
68     {
69         typedef double F;
70         E r;
71         F f = std::generate_canonical<F, std::numeric_limits<F>::digits - 1>(r);
72         assert(f == truncate_fp(
73             (16807 - E::min() +
74             (282475249 - E::min()) * (range + F(1))) /
75             ((range + F(1)) * (range + F(1)))));
76     }
77     {
78         typedef double F;
79         E r;
80         F f = std::generate_canonical<F, std::numeric_limits<F>::digits>(r);
81         assert(f == truncate_fp(
82             (16807 - E::min() +
83             (282475249 - E::min()) * (range + F(1))) /
84             ((range + F(1)) * (range + F(1)))));
85     }
86     {
87         typedef double F;
88         E r;
89         F f = std::generate_canonical<F, std::numeric_limits<F>::digits + 1>(r);
90         assert(f == truncate_fp(
91             (16807 - E::min() +
92             (282475249 - E::min()) * (range + F(1))) /
93             ((range + F(1)) * (range + F(1)))));
94     }
95 
96   return 0;
97 }
98