grpc
third_party
abseil-cpp
absl
random
internal
abseil-cpp/absl/random/internal/generate_real.h
Go to the documentation of this file.
1
// Copyright 2017 The Abseil Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
16
#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
17
18
// This file contains some implementation details which are used by one or more
19
// of the absl random number distributions.
20
21
#include <cstdint>
22
#include <cstring>
23
#include <limits>
24
#include <type_traits>
25
26
#include "absl/meta/type_traits.h"
27
#include "absl/numeric/bits.h"
28
#include "absl/random/internal/fastmath.h"
29
#include "absl/random/internal/traits.h"
30
31
namespace
absl
{
32
ABSL_NAMESPACE_BEGIN
33
namespace
random_internal {
34
35
// Tristate tag types controlling the output of GenerateRealFromBits.
36
struct
GeneratePositiveTag
{};
37
struct
GenerateNegativeTag
{};
38
struct
GenerateSignedTag
{};
39
40
// GenerateRealFromBits generates a single real value from a single 64-bit
41
// `bits` with template fields controlling the output.
42
//
43
// The `SignedTag` parameter controls whether positive, negative,
44
// or either signed/unsigned may be returned.
45
// When SignedTag == GeneratePositiveTag, range is U(0, 1)
46
// When SignedTag == GenerateNegativeTag, range is U(-1, 0)
47
// When SignedTag == GenerateSignedTag, range is U(-1, 1)
48
//
49
// When the `IncludeZero` parameter is true, the function may return 0 for some
50
// inputs, otherwise it never returns 0.
51
//
52
// When a value in U(0,1) is required, use:
53
// GenerateRealFromBits<double, PositiveValueT, true>;
54
//
55
// When a value in U(-1,1) is required, use:
56
// GenerateRealFromBits<double, SignedValueT, false>;
57
//
58
// This generates more distinct values than the mathematical equivalent
59
// `U(0, 1) * 2.0 - 1.0`.
60
//
61
// Scaling the result by powers of 2 (and avoiding a multiply) is also possible:
62
// GenerateRealFromBits<double>(..., -1); => U(0, 0.5)
63
// GenerateRealFromBits<double>(..., 1); => U(0, 2)
64
//
65
template
<
typename
RealType,
// Real type, either float or double.
66
typename
SignedTag =
GeneratePositiveTag
,
// Whether a positive,
67
// negative, or signed
68
// value is generated.
69
bool
IncludeZero =
true
>
70
inline
RealType
GenerateRealFromBits
(
uint64_t
bits
,
int
exp_bias = 0) {
71
using
real_type
= RealType;
72
using
uint_type =
absl::conditional_t<std::is_same<real_type, float>::value
,
73
uint32_t
,
uint64_t
>;
74
75
static_assert(
76
(
std::is_same<double, real_type>::value
||
77
std::is_same<float, real_type>::value
),
78
"GenerateRealFromBits must be parameterized by either float or double."
);
79
80
static_assert(
sizeof
(uint_type) ==
sizeof
(
real_type
),
81
"Mismatched unsinged and real types."
);
82
83
static_assert((std::numeric_limits<real_type>::is_iec559 &&
84
std::numeric_limits<real_type>::radix
== 2),
85
"RealType representation is not IEEE 754 binary."
);
86
87
static_assert((
std::is_same<SignedTag, GeneratePositiveTag>::value
||
88
std::is_same<SignedTag, GenerateNegativeTag>::value
||
89
std::is_same<SignedTag, GenerateSignedTag>::value
),
90
""
);
91
92
static
constexpr
int
kExp = std::numeric_limits<real_type>::digits - 1;
93
static
constexpr uint_type kMask = (
static_cast<
uint_type
>
(1) << kExp) - 1
u
;
94
static
constexpr
int
kUintBits =
sizeof
(uint_type) * 8;
95
96
int
exp = exp_bias +
int
{std::numeric_limits<real_type>::max_exponent - 2};
97
98
// Determine the sign bit.
99
// Depending on the SignedTag, this may use the left-most bit
100
// or it may be a constant value.
101
uint_type sign =
std::is_same<SignedTag, GenerateNegativeTag>::value
102
? (
static_cast<
uint_type
>
(1) << (kUintBits - 1))
103
: 0;
104
if
(
std::is_same<SignedTag, GenerateSignedTag>::value
) {
105
if
(
std::is_same<uint_type, uint64_t>::value
) {
106
sign =
bits
&
uint64_t
{0x8000000000000000};
107
}
108
if
(
std::is_same<uint_type, uint32_t>::value
) {
109
const
uint64_t
tmp
=
bits
&
uint64_t
{0x8000000000000000};
110
sign =
static_cast<
uint32_t
>
(
tmp
>> 32);
111
}
112
// adjust the bits and the exponent to account for removing
113
// the leading bit.
114
bits
=
bits
&
uint64_t
{0x7FFFFFFFFFFFFFFF};
115
exp++;
116
}
117
if
(IncludeZero) {
118
if
(
bits
== 0
u
)
return
0;
119
}
120
121
// Number of leading zeros is mapped to the exponent: 2^-clz
122
// bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
123
int
clz =
countl_zero
(
bits
);
124
bits
<<= (IncludeZero ? clz : (clz & 63));
// remove 0-bits.
125
exp -= clz;
// set the exponent.
126
bits
>>= (63 - kExp);
127
128
// Construct the 32-bit or 64-bit IEEE 754 floating-point value from
129
// the individual fields: sign, exp, mantissa(bits).
130
uint_type val = sign | (
static_cast<
uint_type
>
(exp) << kExp) |
131
(
static_cast<
uint_type
>
(
bits
) & kMask);
132
133
// bit_cast to the output-type
134
real_type
result
;
135
memcpy
(
static_cast<
void
*
>
(&
result
),
static_cast<
const
void
*
>
(&val),
136
sizeof
(
result
));
137
return
result
;
138
}
139
140
}
// namespace random_internal
141
ABSL_NAMESPACE_END
142
}
// namespace absl
143
144
#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
radix
int radix
Definition:
abseil-cpp/absl/strings/internal/pow10_helper_test.cc:31
_gevent_test_main.result
result
Definition:
_gevent_test_main.py:96
absl::random_internal::GenerateNegativeTag
Definition:
abseil-cpp/absl/random/internal/generate_real.h:37
google::protobuf.internal::real_type
FieldDescriptor::Type real_type(FieldType type)
Definition:
bloaty/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc:128
absl::conditional_t
typename std::conditional< B, T, F >::type conditional_t
Definition:
abseil-cpp/absl/meta/type_traits.h:634
absl::random_internal::GenerateSignedTag
Definition:
abseil-cpp/absl/random/internal/generate_real.h:38
u
OPENSSL_EXPORT pem_password_cb void * u
Definition:
pem.h:351
absl::random_internal::GeneratePositiveTag
Definition:
abseil-cpp/absl/random/internal/generate_real.h:36
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition:
third_party/abseil-cpp/absl/base/config.h:171
uint32_t
unsigned int uint32_t
Definition:
stdint-msvc2008.h:80
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
absl::random_internal::GenerateRealFromBits
RealType GenerateRealFromBits(uint64_t bits, int exp_bias=0)
Definition:
abseil-cpp/absl/random/internal/generate_real.h:70
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition:
third_party/abseil-cpp/absl/base/config.h:170
uint64_t
unsigned __int64 uint64_t
Definition:
stdint-msvc2008.h:90
bits
OPENSSL_EXPORT ASN1_BIT_STRING * bits
Definition:
x509v3.h:482
absl::countl_zero
ABSL_INTERNAL_CONSTEXPR_CLZ std::enable_if< std::is_unsigned< T >::value, int >::type countl_zero(T x) noexcept
Definition:
abseil-cpp/absl/numeric/bits.h:77
value
const char * value
Definition:
hpack_parser_table.cc:165
absl
Definition:
abseil-cpp/absl/algorithm/algorithm.h:31
autogen_x86imm.tmp
tmp
Definition:
autogen_x86imm.py:12
grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:25