C语言实现指定位范围掩码生成函数的技术问询
getMask Function in C Alright, let's work through implementing this getMask function in C. First, let's recap the requirements clearly so we're all aligned:
We need an
int-returning functiongetMaskthat takes threeintparameters:
start: The starting bit position (0-indexed, counting from the rightmost bit)end: The ending bit position (must be ≥ start)type: A flag (0 or 1) that defines the mask:
type=1: Bits fromstarttoendare set to 1, all others 0type=0: Bits fromstarttoendare set to 0, all others 1Examples:
getMask(2, 6, 1)returns124(binary00000000 00000000 00000000 01111100)getMask(11, 31, 0)returns a value where bits 11 through 31 are 0, and bits 0 through 10 are 1
Key Observations & Approach
First, we need to generate a base mask where bits start to end are 1. Then we'll invert it if type=0. We'll use unsigned integer types for intermediate calculations to avoid undefined behavior from signed integer shifts (a common pitfall in C).
Step 1: Generate the Base 1-Mask
To create a mask with n consecutive 1s starting at bit start:
- Calculate how many bits we need to set:
num_bits = end - start + 1 - Create a mask of
num_bits1s:(1U << num_bits) - 1(using1Uensures we're working with unsigned values) - Shift this mask left by
startpositions to align it with the target bit range
We need a special case for when end=31 (the highest bit of a 32-bit int): shifting 1U <<32 is undefined, so we use UINT_MAX << start instead (which gives us all bits from start to 31 set to 1).
Step 2: Invert the Mask (if needed)
If type=0, we just invert the base mask using ~mask—since we're using unsigned integers, this gives us a clean inverse without sign-related issues.
Full Implementation
Here's the code with safety checks and edge case handling:
#include <stdint.h> // For UINT_MAX (portable all-1s mask for unsigned 32-bit integers) #include <assert.h> // Optional, for debugging input validation int getMask(int start, int end, int type) { // Validate input (remove assert if you don't want runtime checks) assert(start >= 0 && end < 32 && start <= end); uint32_t base_mask; if (end == 31) { // Special case: cover all bits from start to the highest 32-bit int bit base_mask = UINT_MAX << start; } else { uint32_t num_bits = end - start + 1; base_mask = ((1U << num_bits) - 1) << start; } // Adjust mask based on type if (type == 0) { base_mask = ~base_mask; } // Convert back to int (safe for 32-bit values) return (int)base_mask; }
Testing the Examples
Let's verify the given cases:
getMask(2, 6, 1):num_bits = 6-2+1 =5(1U<<5)-1 =31(binary00011111)- Shift left by 2:
31<<2 =124(binary01111100) type=1, so return124—matches the example.
getMask(11, 31, 0):end=31, sobase_mask = UINT_MAX <<11(all bits 11-31 are 1)type=0, invert to get bits 0-10 set to 1, bits11-31 set to0—exactly what's required.
Notes
- This assumes
intis 32 bits (standard on most modern systems). For 16-bitintsupport, adjust the assertion toend <16and useUINT16_MAXinstead ofUINT_MAX. - The
assertis optional but helps catch invalid input (likestart > endor out-of-range bit positions) during development. Replace it with custom error handling if you need to handle invalid inputs gracefully. - If you can't use
stdint.h, replaceuint32_twithunsigned intandUINT_MAXwith~0U(an unsigned all-1s mask).
内容的提问来源于stack exchange,提问作者bbcob

