-1

We can assume an int is 32 bits in 2's compliment The only Legal operators are: ! ~ & ^ | + << >>

At this point i am using brute force

int a=0x01;
x=(x+1)>>1; //(have tried with just x instead of x+1 as well)
a = a+(!(!x));

... with the last 2 statements repeated 32 times. This adds 1 to a everytime x is shifted one place and != 0 for all 32 bits

Using the test compiler it says my method fails on test case 0x7FFFFFFF (a 0 followed by 31 1's) and says this number requires 32 bits to represent. I dont see why this isnt 31 (which my method computes) Can anyone explain why? And what i need to change to account for this?

James Polley
  • 7,977
  • 2
  • 29
  • 33
Gadesxion
  • 391
  • 2
  • 6
  • 18
  • 3
    http://graphics.stanford.edu/~seander/bithacks.html has all the answers you need in this case. – Daniel Kamil Kozar Feb 03 '12 at 01:55
  • possible duplicate of [# of bits needed to represent a number x](http://stackoverflow.com/questions/9105713/of-bits-needed-to-represent-a-number-x) – Paul R Feb 03 '12 at 07:42

2 Answers2

2

Please try this code to check whether a signed integer x can be fitted into n bits. The function returns 1 when it does and 0 otherwise.

// http://www.cs.northwestern.edu/~wms128/bits.c
int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
  int mask = x >> 31;

  return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}
oon
  • 61
  • 3
2

0x7FFFFFFF does require 32 bits. It could be expressed as an unsigned integer in only 31 bits:

111 1111 1111 1111 1111 1111 1111 1111

but if we interpret that as a signed integer using two's complement, then the leading 1 would indicate that it's negative. So we have to prepend a leading 0:

0 111 1111 1111 1111 1111 1111 1111 1111

which then makes it 32 bits.

As for what you need to change — your current program actually has undefined behavior. If 0x7FFFFFFF (231-1) is the maximum allowed integer value, then 0x7FFFFFFF + 1 cannot be computed. It is likely to result in -232, but there's absolutely no guarantee: the standard allow compilers to do absolutely anything in this case, and real-world compilers do in fact perform optimizations that can happen to give shocking results when you violate this requirement. Similarly, there's no specific guarantee what ... >> 1 will mean if ... is negative, though in this case compilers are required, at least, to choose a specific behavior and document it. (Most compilers choose to produce another negative number by copying the leftmost 1 bit, but there's no guarantee of that.)

So really the only sure fix is either:

  • to rewrite your code as a whole, using an algorithm that doesn't have these problems; or
  • to specifically check for the case that x is 0x7FFFFFFF (returning a hardcoded 32) and the case that x is negative (replacing it with ~x, i.e. -(x+1), and proceeding as usual).
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • There's no finite number of options compilers have to choose between; it's purely implementation-defined. For example the implementation could define that `x>>1` returns 32 bits from a hardware entropy source whenever `x` is negative. :-) – R.. GitHub STOP HELPING ICE Feb 03 '12 at 02:40
  • @R.: Whoops, you're right. What's more, this operation is exactly what standard gives as its example of implementation-defined behavior. I'll fix the answer; thank you! – ruakh Feb 03 '12 at 02:49