比较来自世界各地的卖家的域名和 IT 服务价格

家庭面具 C

建立一点面具的最佳方法是什么? C 从
m

位前面
k

安装然后
n

安装:


00..0 11..1 00..0
k m n


例如, k=1, m=4, n=3 会导致有点面具:


01111000
已邀请:

龙天

赞同来自:

~/~0 << m/ << N

小明明

赞同来自:

所以你问 m 位设置前缀 k 重置位和随后 n 转储位? 我们可以忽视 k, 由于它将主要限于选择整数类型。


mask = //1 << m/ - 1/ << n;

帅驴

赞同来自:

我喜欢这两个决定。 这是另一种涉及我的方式 /可能没有好些/.


//~//unsigned int/0/ << k/ >> /k + n// << n


EDIT:
在我以前的版本中有一个错误 /她没有 unsigned int cast/. 问题是
~0 >> n

补充. 1s 在前面而不是 0s.

是的,这种方法有一个大缺点:他认为你知道标准整数类型的比特数或换句话说,他认为你真的知道 k, 而其他解决方案不依赖 k. 这使我的版本更少或者至少更难传输。 /它也使用 3 换档,加法和按位奉献操作员,这是两个附加操作。/

因此,最好使用其他一个例子。

这是Jonathan Lefefler制作的小型测试应用程序,以比较和检查各种解决方案的结果:


#include <stdio.h>
#include <limits.h>

enum { ULONG_BITS = /sizeof/unsigned long/ * CHAR_BIT/ };

static unsigned long set_mask_1/int k, int m, int n/
{
return ~/~0 &lt;&lt; m/ &lt;&lt; n;
}

static unsigned long set_mask_2/int k, int m, int n/
{
return //1 &lt;&lt; m/ - 1/ &lt;&lt; n;
}

static unsigned long set_mask_3/int k, int m, int n/
{
return //~//unsigned long/0/ &lt;&lt; k/ &gt;&gt; /k + n// &lt;&lt; n;
}

static int test_cases[][2] =
{
{ 1, 0 },
{ 1, 1 },
{ 1, 2 },
{ 1, 3 },
{ 2, 1 },
{ 2, 2 },
{ 2, 3 },
{ 3, 4 },
{ 3, 5 },
};

int main/void/
{
size_t i;
for /i = 0; i &lt; 9; i++/
{
int m = test_cases[i][0];
int n = test_cases[i][1];
int k = ULONG_BITS - /m + n/;
printf/"%d/%d/%d = 0xlX = 0xlX = 0xlX\n", k, m, n,
set_mask_1/k, m, n/,
set_mask_2/k, m, n/,
set_mask_3/k, m, n//;
}
return 0;
}


</limits.h></stdio.h>

君笑尘

赞同来自:

/仅有的/ 对于那些对系统稍微高效的解决方案感兴趣的人 x86 有支持者 BMI2 /Intel Haswell 或者更新 AMD Excavator 或者更新/:


mask = _bzhi_u32/-1,m/<<n;[ <stdio.h="" [code]#include="" [code]_bzhi_u32[="" [code]bzhi[="" code]="" 从指定的位位置删除旧位。="" 内部功能="" 操作说明="" 测试代码:="" 编写此指令。="">
#include <x86intrin.h>
/* gcc -O3 -Wall -m64 -march=haswell bitmsk_mn.c */

unsigned int bitmsk/unsigned int m, unsigned int n/
{
return _bzhi_u32/-1,m/&lt;<n; "k='X\n",k/;' $-1,="" %eax[="" %edi="" %edi,="" %edx="" %edx,="" %esi,="" -1,m="" .="" 0;="" 1="" 2="" 4="" <="" <<n[="" @jonathan="" [code]$.="" [code]_bzhi_u32="" [code]bzhi[="" [code]movl="" [code]shlx[="" a="" a.out="" amd="" bzhi="" code]="" div="" haswell="" int="" intel="" k="000FE000
" main="" printf="" return="" ryzen="" shlx="" {="" }="" }[="" 一个指令小于代码="" 代码片段="" 关于处理器="" 出口:="" 和="" 在="" 对于cycl。="" 带宽="" 延迟b.="" 循环i.="" 或新的和新的="" 编译三个说明="" 这两个指示甚至有带宽。="">
<div class="answer_text">
虽然最好的答案是简单而有效的,但他们没有安装 MSB 对于这种情况
n=0


m=31

:


~/~0 &lt;&lt; 31/ &lt;&lt; 0

=
0111 1111 1111 1111 1111 1111 1111 1111‬



//1 &lt;&lt; 31/-1/ &lt;&lt; 0

=
0111 1111 1111 1111 1111 1111 1111 1111‬


我为32位无符号字提出 /哪个丑陋并且有一个分支/ 如下:


unsigned int create_mask/unsigned int n,unsigned int m/ {
// 0 &lt;= start_bit, end_bit &lt;= 31
return /m - n == 31 ? 0xFFFFFFFF : //1 &lt;&lt; /m-n/+1/-1/ &lt;&lt; n/;
}


这实际上返回范围内的位
[m,n]

/封闭间隔/, 所以
create_mask/0,0/

将返回第一位的掩码 /页 0/, 和
create_mask/4,6/

将返回来自的掩码 4 到 6, 它是。
... 00111 0000

.
</div>
</n;></x86intrin.h></n;[>

郭文康

赞同来自:

虽然最好的答案是简单而有效的,但他们没有安装 MSB 对于这种情况
n=0


m=31

:


~/~0 << 31/ << 0

=
0111 1111 1111 1111 1111 1111 1111 1111‬



//1 << 31/-1/ << 0

=
0111 1111 1111 1111 1111 1111 1111 1111‬


我为32位无符号字提出 /哪个丑陋并且有一个分支/ 如下:


unsigned int create_mask/unsigned int n,unsigned int m/ {
// 0 <= start_bit, end_bit <= 31
return /m - n == 31 ? 0xFFFFFFFF : //1 << /m-n/+1/-1/ << n/;
}


这实际上返回范围内的位
[m,n]

/封闭间隔/, 所以
create_mask/0,0/

将返回第一位的掩码 /页 0/, 和
create_mask/4,6/

将返回来自的掩码 4 到 6, 它是。
... 00111 0000

.

要回复问题请先登录注册