Skip to content

Commit c36f1f0

Browse files
committed
Merge #72: Fix MSVC implementation of CountBits() function
0078bed Ignore `HAVE_CLZ` macro when building with MSVC (Hennadii Stepanov) 1c77291 Fix MSVC implementation of `CountBits()` function (Hennadii Stepanov) Pull request description: The current MSVC-specific implementation of the `CountBits()` function, which uses `_BitScanReverse` and `_BitScanReverse64` intrinsic functions, returns the wrong value with offset 1. See: https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64?view=msvc-170 The second commit makes MSVC ignore a possible `/DHAVE_CLZ` option (as this compiler is not handled by the current build system), which otherwise causes a compiling error. A branch, which allows to test this PR easily, is [here](https://github.com/hebasto/minisketch/commits/221018-bits.test). Fixes #67. ACKs for top commit: sipa: ACK 0078bed Tree-SHA512: 7c4ae68acd11be8a0729c5d5e231fe5da0302ca4543bb5734c8a96d65e190b35155d14945e6afca211270a8d235293d74391bc74ea4a6ee756084aa0b834d87b
2 parents 47f0a2d + 0078bed commit c36f1f0

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

src/int_utils.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,7 @@ constexpr inline I Mask() { return ((I((I(-1)) << (std::numeric_limits<I>::digit
129129
/** Compute the smallest power of two that is larger than val. */
130130
template<typename I>
131131
static inline int CountBits(I val, int max) {
132-
#ifdef HAVE_CLZ
133-
(void)max;
134-
if (val == 0) return 0;
135-
if (std::numeric_limits<unsigned>::digits >= std::numeric_limits<I>::digits) {
136-
return std::numeric_limits<unsigned>::digits - __builtin_clz(val);
137-
} else if (std::numeric_limits<unsigned long>::digits >= std::numeric_limits<I>::digits) {
138-
return std::numeric_limits<unsigned long>::digits - __builtin_clzl(val);
139-
} else {
140-
return std::numeric_limits<unsigned long long>::digits - __builtin_clzll(val);
141-
}
142-
#elif _MSC_VER
132+
#ifdef _MSC_VER
143133
(void)max;
144134
unsigned long index;
145135
unsigned char ret;
@@ -149,7 +139,17 @@ static inline int CountBits(I val, int max) {
149139
ret = _BitScanReverse64(&index, val);
150140
}
151141
if (!ret) return 0;
152-
return index;
142+
return index + 1;
143+
#elif HAVE_CLZ
144+
(void)max;
145+
if (val == 0) return 0;
146+
if (std::numeric_limits<unsigned>::digits >= std::numeric_limits<I>::digits) {
147+
return std::numeric_limits<unsigned>::digits - __builtin_clz(val);
148+
} else if (std::numeric_limits<unsigned long>::digits >= std::numeric_limits<I>::digits) {
149+
return std::numeric_limits<unsigned long>::digits - __builtin_clzl(val);
150+
} else {
151+
return std::numeric_limits<unsigned long long>::digits - __builtin_clzll(val);
152+
}
153153
#else
154154
while (max && (val >> (max - 1) == 0)) --max;
155155
return max;

0 commit comments

Comments
 (0)