1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___RANDOM_GENERATE_CANONICAL_H
10 #define _LIBCPP___RANDOM_GENERATE_CANONICAL_H
13 #include <__random/log2.h>
15 #include <initializer_list>
18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19 # pragma GCC system_header
23 #include <__undef_macros>
25 _LIBCPP_BEGIN_NAMESPACE_STD
29 template <class _RealType
, size_t __bits
, class _URNG
>
30 _LIBCPP_HIDE_FROM_ABI _RealType
generate_canonical(_URNG
& __g
) {
31 const size_t __dt
= numeric_limits
<_RealType
>::digits
;
32 const size_t __b
= __dt
< __bits
? __dt
: __bits
;
33 #ifdef _LIBCPP_CXX03_LANG
34 const size_t __log_r
= __log2
<uint64_t, _URNG::_Max
- _URNG::_Min
+ uint64_t(1)>::value
;
36 const size_t __log_r
= __log2
<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value
;
38 const size_t __k
= __b
/ __log_r
+ (__b
% __log_r
!= 0) + (__b
== 0);
39 const _RealType __rp
= static_cast<_RealType
>(_URNG::max() - _URNG::min()) + _RealType(1);
40 _RealType __base
= __rp
;
41 _RealType __sp
= __g() - _URNG::min();
42 for (size_t __i
= 1; __i
< __k
; ++__i
, __base
*= __rp
)
43 __sp
+= (__g() - _URNG::min()) * __base
;
47 _LIBCPP_END_NAMESPACE_STD
51 #endif // _LIBCPP___RANDOM_GENERATE_CANONICAL_H