0

working on an exercise from Computer Systems: A programmer's perspective and this is what i came up with. Unfortunatly this doesn't work in the case that n=32, if n=32 it doesn't shift x at all so it returns 1 regardless. This is a problem if x=0x80000000 because in this case it should return 0

/* 
 * 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 diff = 32 +(~n + 1);//diff between n and 32
  return !(x ^ ((x << diff) >> diff)); //shifts x left by diff then right by diff leaving the num unchanged if it would fit as an n-bit 2s comp int then xor's with x so it will be !0 if x matches shifted x or !1 otherwise
}
  • Does this answer your question? [Bitwise operations and shifts](https://stackoverflow.com/questions/14792521/bitwise-operations-and-shifts) – BoP Mar 02 '22 at 01:05
  • Why should `x` = 0x80000000 return 0? First, in a 32-bit `int`, you cannot pass 0x80000000; that hexadecimal numeral represents 2^31, and a 32-bit two’s complement integer can only represent −2^31 to +2^31−1. If you mean the case where the bits in `x` are 0x80000000, then the value represented is −2^31. That is representable in an `int`, so the routine should return 1. Why do you say it should return 0? – Eric Postpischil Mar 02 '22 at 01:12
  • @EricPostpischil in this case 0x80000000 is -2147483648 or -2^31 so the twos comp would take 33 bits and wouldn't fit in a 32 bit int. that is why i say that it should return 0. However. I am very new to bitwise operators so if it doesn't make sense to handle this case or im thinking about it wrong please correct me. Thanks. – Abraham Passmore Mar 02 '22 at 01:29
  • You can only legitimately shift a 32-bit integer by an amount in the range 0..31. Using any other value leads to undefined behaviour — you get what you [get](http://www.catb.org/jargon/html/N/nasal-demons.html) and you can't complain, even if your machine turns into a heap of rubble. – Jonathan Leffler Mar 02 '22 at 01:41
  • @JonathanLeffler: There is no shift outside 0 to 31 here. For inputs of `n` from 1 to 32, `diff` is set to 31 to 0. (`int diff = 32 + (~n + 1);` is `int diff = 32-n;` written to avoid subtraction because it is not one of the permitted operations.) – Eric Postpischil Mar 02 '22 at 02:34
  • @AbrahamPassmore: The 32-bit two’s complement representation of −2,147,483,648 is 10000000000000000000000000000000, a.k.a. 0x80000000. −2,147,483,648 is representable in 32 bits. To see this, compile and execute `#include ` / `#include ` / `#include ` / `int main(void) { printf("%" PRId32 "\n", INT32_MIN); }`. It will print “-2147483648”. – Eric Postpischil Mar 02 '22 at 02:37
  • Step 1 is to rewrite this to only use unsigned integers. Doing bitwise arithmetic on signed numbers is dangerous and plain wrong in some 99% of all use-cases. – Lundin Mar 02 '22 at 06:54
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Mar 02 '22 at 11:29

0 Answers0