What is the purpose of “int mask = ~0;”?

前端 未结 6 627
春和景丽
春和景丽 2020-12-29 18:30

I saw the following line of code here in C.

 int mask = ~0;

I have printed the value of mask in C and C++. It always prints

相关标签:
6条回答
  • 2020-12-29 18:51

    C and C++ allow 3 different signed integer formats: sign-magnitude, one's complement and two's complement

    ~0 will produce all-one bits regardless of the sign format the system uses. So it's more portable than -1

    You can add the U suffix (i.e. -1U) to generate an all-one bit pattern portably1. However ~0 indicates the intention clearer: invert all the bits in the value 0 whereas -1 will show that a value of minus one is needed, not its binary representation

    1 because unsigned operations are always reduced modulo the number that is one greater than the largest value that can be represented by the resulting type

    0 讨论(0)
  • 2020-12-29 18:54

    There are multiple ways of encoding numbers across all computer architectures. When using 2's complement this will always be true:~0 == -1. On the other hand, some computers use 1's complement for encoding negative numbers for which the above example is untrue, because ~0 == -0. Yup, 1s complement has negative zero, and that is why it is not very intuitive.

    So to your questions

    • the ~0 is assigned to mask so all the bits in mask are equal 1 -> making mask & sth == sth
    • the ~0 is used to make all bits equal to 1 regardless of the platform used
    • you can use -1 instead of ~0 if you are sure that your computer platform uses 2's complement number encoding

    My personal thought - make your code as much platform-independent as you can. The cost is relatively small and the code becomes fail proof

    0 讨论(0)
  • 2020-12-29 19:04

    You are studying a coding challenge with a number of restrictions on operators and language constructions to perform given tasks.

    The first problem is return the value -1 without the use of the - operator.

    On machines that represent negative numbers with two's complement, the value -1 is represented with all bits set to 1, so ~0 evaluates to -1:

    /* 
     * minusOne - return a value of -1 
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 2
     *   Rating: 1
     */
    int minusOne(void) {
      // ~0 = 111...111 = -1
      return ~0;
    }
    

    Other problems in the file are not always implemented correctly. The second problem, returning a boolean value representing the fact the an int value would fit in a 16 bit signed short has a flaw:

    /* 
     * fitsShort - return 1 if x can be represented as a 
     *   16-bit, two's complement integer.
     *   Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 8
     *   Rating: 1
     */
    int fitsShort(int x) {
      /* 
       * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
       * so after shift, if x remains the same, then it means that x can be represent as 16-bit
      */
      return !(((x << 16) >> 16) ^ x); 
    }
    

    Left shifting a negative value or a number whose shifted value is beyond the range of int has undefined behavior, right shifting a negative value is implementation defined, so the above solution is incorrect (although it is probably the expected solution).

    0 讨论(0)
  • 2020-12-29 19:11

    That on a 2's complement platform (that is assumed) gives you -1, but writing -1 directly is forbidden by the rules (only integers 0..255, unary !, ~ and binary &, ^, |, +, << and >> are allowed).

    0 讨论(0)
  • 2020-12-29 19:12

    It's a portable way to set all the binary bits in an integer to 1 bits without having to know how many bits are in the integer on the current architecture.

    0 讨论(0)
  • 2020-12-29 19:14

    Loooong ago this was how you saved memory on extremely limited equipment such as the 1K ZX 80 or ZX 81 computer. In BASIC, you would

    Let X = NOT PI
    

    rather than

    LET X = 0
    

    Since numbers were stored as 4 byte floating points, the latter takes 2 bytes more than the first NOT PI alternative, where each of NOT and PI takes up a single byte.

    0 讨论(0)
提交回复
热议问题