C 将负数转换为正数但保持正数不变
我想对一个数字应用位掩码,该数字将模拟2的补码编码有符号32位整数的绝对值函数。到目前为止,我已经C 将负数转换为正数但保持正数不变,c,bit-manipulation,C,Bit Manipulation,我想对一个数字应用位掩码,该数字将模拟2的补码编码有符号32位整数的绝对值函数。到目前为止,我已经 int absoluteValue(int x) { int sign = x >> 31; //get most significant byte...all 1's if x is < 0, all 0's if x >= 0 int negated = (~x + 1) & sign; //negates the number if neg
int absoluteValue(int x) {
int sign = x >> 31; //get most significant byte...all 1's if x is < 0, all 0's if x >= 0
int negated = (~x + 1) & sign; //negates the number if negative, sets to 0 if positive
//what should go here???
}
int绝对值(int x){
int sign=x>>31;//获取最高有效字节…如果x<0,则所有1;如果x>=0,则所有0
int negated=(~x+1)&sign;//如果为负数,则对数字求反;如果为正数,则将其设置为0
//这里应该放什么???
}
我走的方向对吗?我真的不确定从这里走到哪里(主要是如何应用遮罩来保持原始正值)。我也不想使用任何条件语句奇怪的问题。那怎么办
return (negated << 1) + x;
return(否定>31;//获取最高有效字节…如果x<0,则所有1;如果x>=0,则所有0
int negated=(~x+1)&sign;//如果为负数,则对数字求反;如果为正数,则将其设置为0
返回(否定奇怪的问题。关于
return (negated << 1) + x;
return(否定>31;//获取最高有效字节…如果x<0,则所有1;如果x>=0,则所有0
int negated=(~x+1)&sign;//如果为负数,则对数字求反;如果为正数,则将其设置为0
返回(否定最后一部分
negated = (~x + 1) & sign;
是错误的,您将得到1或0,您必须创建一个包含所有
前31位为0,最后一位为0或1
假设对于您的目标,您处理的是带2的32位整数
作为补充,您可以这样做:
#include <stdio.h>
// assuming 32bit, 2 complement
int sign_inverse(int n)
{
int mask = ~n & 0x80000000U;
if(n == 0)
mask = 0;
return (~n + 1) | mask;
}
int main(void)
{
int a = 5;
int b = -4;
int c = 54;
int d = 0;
printf("sign_inverse(%d) = %d\n", a, sign_inverse(a));
printf("sign_inverse(%d) = %d\n", b, sign_inverse(b));
printf("sign_inverse(%d) = %d\n", c, sign_inverse(c));
printf("sign_inverse(%d) = %d\n", d, sign_inverse(d));
return 0;
}
最后一部分
negated = (~x + 1) & sign;
是错误的,您将得到1或0,您必须创建一个包含所有
前31位为0,最后一位为0或1
假设对于您的目标,您处理的是带2的32位整数
作为补充,您可以这样做:
#include <stdio.h>
// assuming 32bit, 2 complement
int sign_inverse(int n)
{
int mask = ~n & 0x80000000U;
if(n == 0)
mask = 0;
return (~n + 1) | mask;
}
int main(void)
{
int a = 5;
int b = -4;
int c = 54;
int d = 0;
printf("sign_inverse(%d) = %d\n", a, sign_inverse(a));
printf("sign_inverse(%d) = %d\n", b, sign_inverse(b));
printf("sign_inverse(%d) = %d\n", c, sign_inverse(c));
printf("sign_inverse(%d) = %d\n", d, sign_inverse(d));
return 0;
}
请注意,不保证2的补码表示,也不保证运算符>
对有符号值的行为,其中结果get“填充”了1
-位是实现定义的(例如,参见):
对于负LHS,LHS>>RHS的值由实现定义
在大多数实现中,它执行算术右移
(因此结果仍然为负值)。因此,在大多数实现中,
右移位有符号的LHS用
原始符号位(即,如果为非负,则为0,如果为负,则为1
否定)
但是如果你认为这是给定的,如果你只想使用位操作和操作符+
,你已经走上了正确的方向
唯一的一点是,您应该考虑您创建的掩码(即您的符号
),因为您仅在x
为负数的情况下切换x
的位。您可以通过XOR运算符实现这一点,如下所示:
int x = -3000;
unsigned int mask = x >> 31;
int sign = mask & 0x01;
int positive = (x^mask) + sign;
printf("x:%d mask:%0X sign:%d positive:%d\n",x,mask,sign,positive);
请注意,不保证2的补码表示,也不保证运算符>
对有符号值的行为,其中结果get“填充”了1
-位是实现定义的(例如,参见):
对于负LHS,LHS>>RHS的值由实现定义
在大多数实现中,它执行算术右移
(因此结果仍然为负值)。因此,在大多数实现中,
右移位有符号的LHS用
原始符号位(即,如果为非负,则为0,如果为负,则为1
否定)
但是如果你认为这是给定的,如果你只想使用位操作和操作符+
,你已经走上了正确的方向
唯一的一点是,您应该考虑您创建的掩码(即您的符号
),因为您仅在x
为负数的情况下切换x
的位。您可以通过XOR运算符实现这一点,如下所示:
int x = -3000;
unsigned int mask = x >> 31;
int sign = mask & 0x01;
int positive = (x^mask) + sign;
printf("x:%d mask:%0X sign:%d positive:%d\n",x,mask,sign,positive);
对不起,你的代码是什么语言,你可以同时标记C和C++,你能删除其中的一个标签来澄清你的问题吗?<代码>(x<0){x= -x;} /Cord>。不能保证任何系统使用2的补码。我不想使用条件语句,所以没有IFS,TrnAcess,ETCIS这个作业吗?<代码>(x>(sixof x*CARY-BIT - 1))
告诉您有符号值的数字是否为负数。(例如,如果设置了符号位),如果为负数,则返回(~x+1)
否则只返回x
(请记住,2的补语中仅表示负数,正数不变)对不起,你的代码是什么语言,你可以同时标记C和C++,你能删除其中的一个标签来澄清你的问题吗?<代码>(x<0){x= -x;} /Cord>。不能保证任何系统使用2的补码。我不想使用条件语句,所以没有IFS,TrnAcess,ETCIS这个作业吗?<代码>(x>(sixof x*CARY-BIT - 1))
告诉您有符号值的数字是否为负数。(例如,如果设置了符号位),如果为负数,则返回(~x+1)
否则只返回x
(请记住,2的补语中仅表示负数,正数不变)@user1228123正数形式的&
是错误的。如果数字是正数,则OP的符号
变量为0。任何按位和0为0的值,与的值无关(~x+1)
进行计算。如果该数字为负数,则结果是实现定义为编译器可能进行算术移位。抱歉,Pablo,删除注释太匆忙。这是正确的,因为右移负数会将最高有效位中的1放入。否则,负数将在其第一个右位移位时更改符号。更清楚地说,这意味着符号为0xFFFFFF或0x00000000(-1或0)@user1228123正数形式如果肯定是错误的,那么只有在编译器进行算术移位时,负数形式才可能是正确的。negated可能是一个误导性的变量名,但正如Howard Wang最初所说,正数形式为0