TR-mbed 1.0
Loading...
Searching...
No Matches
random_without_cast_overflow.h
Go to the documentation of this file.
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2020 C. Antonio Sanchez <cantonios@google.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10// Utilities for generating random numbers without overflows, which might
11// otherwise result in undefined behavior.
12
13namespace Eigen {
14namespace internal {
15
16// Default implementation assuming SrcScalar fits into TgtScalar.
17template <typename SrcScalar, typename TgtScalar, typename EnableIf = void>
19 static SrcScalar value() { return internal::random<SrcScalar>(); }
20};
21
22// Signed to unsigned integer widening cast.
23template <typename SrcScalar, typename TgtScalar>
25 SrcScalar, TgtScalar,
26 typename internal::enable_if<NumTraits<SrcScalar>::IsInteger && NumTraits<TgtScalar>::IsInteger &&
27 !NumTraits<TgtScalar>::IsSigned &&
28 (std::numeric_limits<SrcScalar>::digits < std::numeric_limits<TgtScalar>::digits ||
29 (std::numeric_limits<SrcScalar>::digits == std::numeric_limits<TgtScalar>::digits &&
30 NumTraits<SrcScalar>::IsSigned))>::type> {
31 static SrcScalar value() {
32 SrcScalar a = internal::random<SrcScalar>();
33 return a < SrcScalar(0) ? -(a + 1) : a;
34 }
35};
36
37// Integer to unsigned narrowing cast.
38template <typename SrcScalar, typename TgtScalar>
40 SrcScalar, TgtScalar,
42 NumTraits<SrcScalar>::IsInteger && NumTraits<TgtScalar>::IsInteger && !NumTraits<SrcScalar>::IsSigned &&
43 (std::numeric_limits<SrcScalar>::digits > std::numeric_limits<TgtScalar>::digits)>::type> {
44 static SrcScalar value() {
45 TgtScalar b = internal::random<TgtScalar>();
46 return static_cast<SrcScalar>(b < TgtScalar(0) ? -(b + 1) : b);
47 }
48};
49
50// Integer to signed narrowing cast.
51template <typename SrcScalar, typename TgtScalar>
53 SrcScalar, TgtScalar,
55 NumTraits<SrcScalar>::IsInteger && NumTraits<TgtScalar>::IsInteger && NumTraits<SrcScalar>::IsSigned &&
56 (std::numeric_limits<SrcScalar>::digits > std::numeric_limits<TgtScalar>::digits)>::type> {
57 static SrcScalar value() { return static_cast<SrcScalar>(internal::random<TgtScalar>()); }
58};
59
60// Unsigned to signed integer narrowing cast.
61template <typename SrcScalar, typename TgtScalar>
63 SrcScalar, TgtScalar,
64 typename internal::enable_if<NumTraits<SrcScalar>::IsInteger && NumTraits<TgtScalar>::IsInteger &&
65 !NumTraits<SrcScalar>::IsSigned && NumTraits<TgtScalar>::IsSigned &&
66 (std::numeric_limits<SrcScalar>::digits ==
67 std::numeric_limits<TgtScalar>::digits)>::type> {
68 static SrcScalar value() { return internal::random<SrcScalar>() / 2; }
69};
70
71// Floating-point to integer, full precision.
72template <typename SrcScalar, typename TgtScalar>
74 SrcScalar, TgtScalar,
76 !NumTraits<SrcScalar>::IsInteger && !NumTraits<SrcScalar>::IsComplex && NumTraits<TgtScalar>::IsInteger &&
77 (std::numeric_limits<TgtScalar>::digits <= std::numeric_limits<SrcScalar>::digits)>::type> {
78 static SrcScalar value() { return static_cast<SrcScalar>(internal::random<TgtScalar>()); }
79};
80
81// Floating-point to integer, narrowing precision.
82template <typename SrcScalar, typename TgtScalar>
84 SrcScalar, TgtScalar,
86 !NumTraits<SrcScalar>::IsInteger && !NumTraits<SrcScalar>::IsComplex && NumTraits<TgtScalar>::IsInteger &&
87 (std::numeric_limits<TgtScalar>::digits > std::numeric_limits<SrcScalar>::digits)>::type> {
88 static SrcScalar value() {
89 // NOTE: internal::random<T>() is limited by RAND_MAX, so random<int64_t> is always within that range.
90 // This prevents us from simply shifting bits, which would result in only 0 or -1.
91 // Instead, keep least-significant K bits and sign.
92 static const TgtScalar KeepMask = (static_cast<TgtScalar>(1) << std::numeric_limits<SrcScalar>::digits) - 1;
93 const TgtScalar a = internal::random<TgtScalar>();
94 return static_cast<SrcScalar>(a > TgtScalar(0) ? (a & KeepMask) : -(a & KeepMask));
95 }
96};
97
98// Integer to floating-point, re-use above logic.
99template <typename SrcScalar, typename TgtScalar>
101 SrcScalar, TgtScalar,
102 typename internal::enable_if<NumTraits<SrcScalar>::IsInteger && !NumTraits<TgtScalar>::IsInteger &&
103 !NumTraits<TgtScalar>::IsComplex>::type> {
104 static SrcScalar value() {
105 return static_cast<SrcScalar>(random_without_cast_overflow<TgtScalar, SrcScalar>::value());
106 }
107};
108
109// Floating-point narrowing conversion.
110template <typename SrcScalar, typename TgtScalar>
112 SrcScalar, TgtScalar,
113 typename internal::enable_if<!NumTraits<SrcScalar>::IsInteger && !NumTraits<SrcScalar>::IsComplex &&
114 !NumTraits<TgtScalar>::IsInteger && !NumTraits<TgtScalar>::IsComplex &&
115 (std::numeric_limits<SrcScalar>::digits >
116 std::numeric_limits<TgtScalar>::digits)>::type> {
117 static SrcScalar value() { return static_cast<SrcScalar>(internal::random<TgtScalar>()); }
118};
119
120// Complex to non-complex.
121template <typename SrcScalar, typename TgtScalar>
123 SrcScalar, TgtScalar,
124 typename internal::enable_if<NumTraits<SrcScalar>::IsComplex && !NumTraits<TgtScalar>::IsComplex>::type> {
126 static SrcScalar value() { return SrcScalar(random_without_cast_overflow<SrcReal, TgtScalar>::value(), 0); }
127};
128
129// Non-complex to complex.
130template <typename SrcScalar, typename TgtScalar>
132 SrcScalar, TgtScalar,
133 typename internal::enable_if<!NumTraits<SrcScalar>::IsComplex && NumTraits<TgtScalar>::IsComplex>::type> {
136};
137
138// Complex to complex.
139template <typename SrcScalar, typename TgtScalar>
141 SrcScalar, TgtScalar,
142 typename internal::enable_if<NumTraits<SrcScalar>::IsComplex && NumTraits<TgtScalar>::IsComplex>::type> {
149};
150
151} // namespace internal
152} // namespace Eigen
ArrayXXi a
Definition Array_initializer_list_23_cxx11.cpp:1
Scalar * b
Definition benchVecAdd.cpp:17
Namespace containing all symbols from the Eigen library.
Definition bench_norm.cpp:85
Definition BandTriangularSolver.h:13
Definition Meta.h:273
Definition random_without_cast_overflow.h:18
static SrcScalar value()
Definition random_without_cast_overflow.h:19
Definition ForwardDeclarations.h:17