将C中给定位置的n位从x复制到y
我正在学习C,我还是一个非常初学者 我的问题如下。我有一个未签名的int x和一个未签名的int y。我想把n位从位置p从x复制到y上的相同位置。我发现了一些类似的问题,但在C语言中没有,大多数情况下,如果取最右边或最左边的位,问题会稍微不同。我还想找到一个不依赖于机器上整数表示的解决方案 这就是我所做的将C中给定位置的n位从x复制到y,c,bit-manipulation,C,Bit Manipulation,我正在学习C,我还是一个非常初学者 我的问题如下。我有一个未签名的int x和一个未签名的int y。我想把n位从位置p从x复制到y上的相同位置。我发现了一些类似的问题,但在C语言中没有,大多数情况下,如果取最右边或最左边的位,问题会稍微不同。我还想找到一个不依赖于机器上整数表示的解决方案 这就是我所做的 unsigned fix_bits(unsigned x, unsigned y, int n, int p) { unsigned u1,u2,u3,u4,x1,y1,yf;
unsigned fix_bits(unsigned x, unsigned y, int n, int p)
{
unsigned u1,u2,u3,u4,x1,y1,yf;
u1 = ~0; /*vector of 1*/
u2 = (u1>>n); /*0 from 0 to n-1 and 1s*/
u3 = ~(u2);/*1 from 0 to n-1 and 0s*/
u4 = u3>>p;/*0 from 0 to p-1, n 1 from p to p+n+1 and 0s*/
x1 = (x & u4);/*only keep n bits of x from position p*/
y1 = (y | u4);/*set y bit from p to (p+n+1) to 1, rest remains unchanged (0 | bit = bit)*/
yf = (x1 | y1);
return yf;
}
但它不起作用:
在28到32的位置3放置2位的结果是402653216
有人知道我做错了什么吗
非常感谢您关于此问题:将n位从位置p从x复制到y上的同一位置
代码的结果与OP中的相同:
unsigned int x = 0xffffffff;
unsigned int y = 0x00000000;
unsigned int z = 0x00000000;
z = fix_bits(x, y, 5, 5);
看起来您是从目标号码的错误端开始操作的。将逻辑更改为从右侧(LSB)工作,而不是从左侧(MSB)
试试这个:
unsigned fix_bits(unsigned x, unsigned y, int n, int p)
{
unsigned a, b, c, d, e;
int mask;
//Get mask
mask = ((1<<(n))-1)<<(p-n); //[edit] corrected, was ...<<p, is ...<<(p-n)
//apply mask to destination,
//XOR that with repositioned, BITwise NOTed source and apply mask
/*so you can do these steps:
a = mask|y;
b = ~x;
c = b<<p;
d = c&mask;
e = d^a;
return e;*/
//or do this one:
return ((mask&(~x<<p))^(mask|y)); //same thing
}
校正掩模(后的结果是关于问题:将n位从x位置p复制到y位置相同
代码的结果与OP中的相同:
unsigned int x = 0xffffffff;
unsigned int y = 0x00000000;
unsigned int z = 0x00000000;
z = fix_bits(x, y, 5, 5);
看起来您是从目标编号的错误一端操作的。请将逻辑更改为从右侧(LSB)而不是从左侧(MSB)工作
试试这个:
unsigned fix_bits(unsigned x, unsigned y, int n, int p)
{
unsigned a, b, c, d, e;
int mask;
//Get mask
mask = ((1<<(n))-1)<<(p-n); //[edit] corrected, was ...<<p, is ...<<(p-n)
//apply mask to destination,
//XOR that with repositioned, BITwise NOTed source and apply mask
/*so you can do these steps:
a = mask|y;
b = ~x;
c = b<<p;
d = c&mask;
e = d^a;
return e;*/
//or do this one:
return ((mask&(~x<<p))^(mask|y)); //same thing
}
结果在对掩码(进行纠正后,您的掩码错误。请尝试:
unsigned mask = ((1 << n) - 1) << p;
return (y & ~mask) | (x & mask);
unsigned mask=((1您的掩码搞错了。请尝试:
unsigned mask = ((1 << n) - 1) << p;
return (y & ~mask) | (x & mask);
unsignedmask=((1所以我的最终工作解决方案是
unsigned fix_bits(unsigned x, unsigned y, int n, int p)
{
unsigned u1,u2,u3,u4,x1,y1,yf;
u1 = ~0; /*vector of 1*/
u2 = (u1<<n); /*0 from 0 to n-1 and 1s*/
u3 = ~(u2);/*1 from 0 to n-1 and 0s*/
u4 = u3<<p;/*0 from 0 to p-1, n 1 from p to p+n+1 and 0s*/
x1 = (x & u4);/*only keep n bits of x from position p*/
y1 = (y | u4);/*set y bit from p to (p+n+1) to 1, rest remains unchanged (0 | bit = bit)*/
yf = (x1 | y1);
return yf;
}
unsigned fix_位(unsigned x,unsigned y,int n,int p)
{
无符号u1、u2、u3、u4、x1、y1、yf;
u1=~0;/*1的向量*/
u2=(u1所以我的最终工作解是
unsigned fix_bits(unsigned x, unsigned y, int n, int p)
{
unsigned u1,u2,u3,u4,x1,y1,yf;
u1 = ~0; /*vector of 1*/
u2 = (u1<<n); /*0 from 0 to n-1 and 1s*/
u3 = ~(u2);/*1 from 0 to n-1 and 0s*/
u4 = u3<<p;/*0 from 0 to p-1, n 1 from p to p+n+1 and 0s*/
x1 = (x & u4);/*only keep n bits of x from position p*/
y1 = (y | u4);/*set y bit from p to (p+n+1) to 1, rest remains unchanged (0 | bit = bit)*/
yf = (x1 | y1);
return yf;
}
unsigned fix_位(unsigned x,unsigned y,int n,int p)
{
无符号u1、u2、u3、u4、x1、y1、yf;
u1=~0;/*1的向量*/
u2=(u1我需要一个类似的函数来构建一个NES模拟器。使用@RYKER的解决方案,我为uint16\u t
创建了一个稍微通用的函数。它可能会被优化。当source\u pos=dest\u pos
时,它也应该满足原始海报的要求
也许有人在寻求解决一般案件时被带到这里,会发现这很有帮助
/*
* This was fun to figure out. Copy num bits at source_pos from source
* into dest at dest_pos. Positions start at 0, the LSB.
*/
uint16_t set_bits(uint16_t source, uint16_t dest, int num, int source_pos, int dest_pos)
{
unsigned long mask = ((1UL<<(num))-1UL)<<(source_pos);
if (dest_pos >= source_pos) {
return (dest & (~(mask << dest_pos))) | ((source & mask) << dest_pos);
}
return (dest & (~(mask >> (source_pos - dest_pos)))) | ((source & mask) >> (source_pos - dest_pos));
/*
*这很有趣。从源位置复制源位置的num位
*在目标位置进入目标位置。从0开始,LSB。
*/
uint16设置位(uint16源、uint16目标、整数、整数源位置、整数目标位置)
{
unsigned long mask=((1UL我需要一个类似的函数来构建一个NES模拟器。使用@ryker的解决方案,我为uint16\u t
创建了一个稍微更通用的函数。它可能会被优化。当source\u pos=dest\u pos
时,它也应该满足原始海报的要求
也许有人在寻求解决一般案件时被带到这里,会发现这很有帮助
/*
* This was fun to figure out. Copy num bits at source_pos from source
* into dest at dest_pos. Positions start at 0, the LSB.
*/
uint16_t set_bits(uint16_t source, uint16_t dest, int num, int source_pos, int dest_pos)
{
unsigned long mask = ((1UL<<(num))-1UL)<<(source_pos);
if (dest_pos >= source_pos) {
return (dest & (~(mask << dest_pos))) | ((source & mask) << dest_pos);
}
return (dest & (~(mask >> (source_pos - dest_pos)))) | ((source & mask) >> (source_pos - dest_pos));
/*
*这很有趣。从源位置复制源位置的num位
*在目标位置进入目标位置。从0开始,LSB。
*/
uint16设置位(uint16源、uint16目标、整数、整数源位置、整数目标位置)
{
无符号长掩码=((1UL<代码>无符号字符
复制位(无符号字符数、无符号字符数、字符开始关闭、字符结束关闭)
{
无符号字符u1=0;
无符号字符u2=0;
u1=~u1;
u1=(u1>>((8*sizeof(num_S))-1-结束关闭+开始关闭));
u1=(u1无符号字符
复制位(无符号字符数、无符号字符数、字符开始关闭、字符结束关闭)
{
无符号字符u1=0;
无符号字符u2=0;
u1=~u1;
u1=(u1>>((8*sizeof(num_S))-1-结束关闭+开始关闭));
u1=(u1首先,位置从最高有效位开始计数。这是完全可能的,但不寻常。其次,您的mux已损坏。尝试y1=y&~u4
将2位放在28到32的第3位的预期结果是什么?我是从二进制查看结果来假设的(见下图),即您只需要从LSB而不是MSB进行操作。这是一个正确的假设吗?(即,假设您确实希望从LSB开始工作,并从位置向LSB(即向右)计数,而不是从位置5向左5位开始,而是从位置5向右5位开始)?我只是s*pid,我想…下面提出的解决方案可能是正确的,但我只想使用,实际上,我使用了MSB表示操作,同时考虑了LSB表示法…所有的评论都是正确的和有帮助的。我要感谢大家!只有通过将左移与右移颠倒,我才做到了我想要的!首先,位置从最高有效位开始计数。这是完全可能的,但不常见。其次,您的mux已损坏。请尝试将2位放置在28到32的第3位的预期结果是什么?我是通过查看二进制结果来假设的(见下图),即您只需要从LSB而不是MSB进行操作。这是一个正确的假设吗?(即,假设您确实希望从LSB开始工作,并从位置向LSB(即向右)计数,而不是从位置5向左5位开始,而是从位置5向右5位开始)?我只是s*pid,我想…下面提出的解决方案可能是正确的,但我只想使用AND左右的ac