// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
// Returns true iff |value| is a power of 2. template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>>
constexpr inlinebool IsPowerOfTwo(T value) { // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits. // // Only positive integers with a single bit set are powers of two. If only one // bit is set in x (e.g. 0b00000100000000) then |x-1| will have that bit set // to zero and all bits to its right set to 1 (e.g. 0b00000011111111). Hence // |x & (x-1)| is 0 iff x is a power of two. return value > 0 && (value & (value - 1)) == 0;
}
// Round up |size| to a multiple of alignment, which must be a power of two. inline size_t Align(size_t size, size_t alignment) {
DCHECK(IsPowerOfTwo(alignment)); return (size + alignment - 1) & ~(alignment - 1);
}
// Round down |size| to a multiple of alignment, which must be a power of two. inline size_t AlignDown(size_t size, size_t alignment) {
DCHECK(IsPowerOfTwo(alignment)); return size & ~(alignment - 1);
}
// CountLeadingZeroBits(value) returns the number of zero bits following the // most significant 1 bit in |value| if |value| is non-zero, otherwise it // returns {sizeof(T) * 8}. // Example: 00100010 -> 2 // // CountTrailingZeroBits(value) returns the number of zero bits preceding the // least significant 1 bit in |value| if |value| is non-zero, otherwise it // returns {sizeof(T) * 8}. // Example: 00100010 -> 1 // // C does not have an operator to do this, but fortunately the various // compilers have built-ins that map to fast underlying processor instructions. #ifdefined(COMPILER_MSVC)
// __builtin_clz has undefined behaviour for an input of 0, even though there's // clearly a return value that makes sense, and even though some processor clz // instructions have defined behaviour for 0. We could drop to raw __asm__ to // do better, but we'll avoid doing that unless we see proof that we need to. template <typename T, unsigned bits = sizeof(T) * 8>
ALWAYS_INLINE typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8, unsigned>::type
CountLeadingZeroBits(T value) {
static_assert(bits > 0, "invalid instantiation"); return LIKELY(value)
? bits == 64
? __builtin_clzll(static_cast<uint64_t>(value))
: __builtin_clz(static_cast<uint32_t>(value)) - (32 - bits)
: bits;
}
// Returns the integer i such as 2^i <= n < 2^(i+1) inlineint Log2Floor(uint32_t n) { return 31 - CountLeadingZeroBits(n);
}
// Returns the integer i such as 2^(i-1) < n <= 2^i inlineint Log2Ceiling(uint32_t n) { // When n == 0, we want the function to return -1. // When n == 0, (n - 1) will underflow to 0xFFFFFFFF, which is // why the statement below starts with (n ? 32 : -1). return (n ? 32 : -1) - CountLeadingZeroBits(n - 1);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.