我正在测试函数fitsBits(int x,int n),我发现有一个条件不适合这个函数,有什么问题?
/*
* fitsBits - return 1 if x can be represented as an
* n-bit, two's complement integer.
* 1 <= n <= 32
* Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 2
*/
int fitsBits(int x, int n) {
int r, c;
c = 33 + ~n;
r = !(((x << c)>>c)^x);
return r;
}
似乎它在
中给出了错误的答案fitsBits(0x80000000, 0x20);
它给了我1,但实际上应该是0 ...... 我该怎么办呢? 谢谢!
答案 0 :(得分:1)
对于签名类型,未定义导致溢出的左移。因此,编译器可以将(x<<c)>>c
简化为x
,并将整个函数简化为return 1;
。
可能你想使用无符号类型。
代码中未定义行为的第二个原因是c
可能大于或等于int的宽度。超过整数类型宽度的移位是未定义的行为。
答案 1 :(得分:1)
fitsBits(0x80000000, 0x20);
此函数返回1
,因为函数的第一个参数是int
,这是(实际上这些天)32位有符号整数。签名32位整数可以表示的最大值是0x7FFFFFFF,它小于您传入的值。因此,您的值被截断并变为-0x80000000
,这是32位整数可以表示的值。因此,您的函数返回1
(是的,我的第一个参数是可以使用0x20 = 32
位表示的东西)。
如果您希望函数将数字0x80000000
正确地分类为无法使用32位表示的内容,则需要更改函数的第一个参数的类型。一个选项会使用unsigned int
,但是根据您的问题定义,您似乎需要正确处理负数,因此您的剩余选项为long long int
,可以保存{{1}之间的数字}和-0x8000000000000000
。
您需要进行更多调整:您需要使用0x7FFFFFFFFFFFFFFF
后缀明确指定常量属于long long
类型,现在需要按LL
换算,不是64 - c
:
32 - c
指向IDEONE的链接:http://ideone.com/G8I3kZ
答案 2 :(得分:-2)
r = (((x << c)>>c)^x); //This will give you 0, meaning r = 0;
OR
r = !((x << c)>>c);
您的功能可以简化为
int fitsBits(int x) {
int r, c;
c = 33;
r = (((x << c)>>c)^x);
return r;
}
请注意,当NOT(!
)被带来时,您要求r