I am testing the function fitsBits(int x, int n) on my own and I figure out there is a condition that doesn't fit in this function, what is the problem?
/*
* 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;
}
It seems like it gives the wrong answer in
fitsBits(0x80000000, 0x20);
It gives me 1, but actually it should be 0... How could I fix it? Thank you!
fitsBits(0x80000000, 0x20);
This function returns 1
, because the first argument of your function is int
, which is (in practice these days) a 32 bit signed integer. The largest value that signed 32 bit integer can represent is 0x7FFFFFFF, which is less than the value you are passing in. Because of that your value gets truncated and becomes -0x80000000
, something that 32 bit integer can represent. Therefore your function returns 1
(yes, my first argument is something that can be represented using 0x20 = 32
bits).
If you want your function to properly classify number 0x80000000
as something that cannot be represented using 32 bits, you need to change the type of the first argument of your function. One options would've been using an unsigned int
, but from your problem definition it seems like you need to properly handle negative numbers, so your remaining option is long long int
, that can hold numbers between -0x8000000000000000
and 0x7FFFFFFFFFFFFFFF
.
You will need to do couple more adjustments: you need to explicitly specify that your constant is of type long long
by using LL
suffix, and you now need to shift by 64 - c
, not by 32 - c
:
#include <stdio.h>
int fitsBits(long long x, int n) {
long long r;
int c;
c = 65 + ~n;
r = !(((x << c)>>c)^x);
return r;
}
int main() {
printf("%d\n", fitsBits(0x80000000LL, 0x20));
return 0;
}
Link to IDEONE: http://ideone.com/G8I3kZ