Подтвердить что ты не робот

Какова цель "int mask = ~ 0;"?

Я видел следующую строку кода здесь в C.

 int mask = ~0;

Я напечатал значение mask в C и С++. Он всегда печатает -1.

Итак, у меня есть несколько вопросов:

  • Зачем присваивать значение ~0 переменной маска?
  • Какова цель ~0?
  • Можно ли использовать -1 вместо ~0?
4b9b3361

Ответ 1

Это переносимый способ установить все двоичные биты в целое число в 1 бит, не зная, сколько бит находится в целочисленном размере в текущей архитектуре.

Ответ 2

C и С++ допускают 3 разных знаковых целочисленных формата: знак-величина, одно дополнение и два дополнения

~0 будет производить все-один бит независимо от формата знака, который использует система. Поэтому он более портативен, чем -1

Более того, ~0 указывает очиститель намерений: инвертируйте все биты в значение 0, тогда как -1 покажет, что требуется значение минус единица, а не его двоичное представление

Ответ 3

Это на платформе с двумя дополнениями (предположительно) дает вам -1, но писать -1 напрямую запрещено правилами (только целые числа 0..255, унарные !, ~ и двоичные &, ^, |, +, << и >>).

Ответ 4

Вы изучаете проблему кодирования с рядом ограничений на операторы и языковые конструкции для выполнения заданных задач.

Первая проблема - вернуть значение -1 без использования оператора -.

На машинах, представляющих отрицательные числа с двумя дополнениями, значение -1 представляется со всеми битами, установленными на 1, поэтому ~0 оценивается как -1:

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

Другие проблемы в файле не всегда выполняются правильно. Вторая проблема, возвращающая логическое значение, представляющее факт, что значение a int будет соответствовать 16-битовому знаку short имеет недостаток:

/* 
 * fitsShort - return 1 if x can be represented as a 
 *   16-bit, two 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); 
}

Левое смещение отрицательного значения или числа, смещенное значение которого находится за пределами диапазона int, имеет поведение undefined, смещение вправо отрицательного значения определяется реализацией, поэтому приведенное выше решение неверно (хотя это, вероятно, ожидается раствора).

Ответ 5

Loooong назад это было то, как вы сохранили память на крайне ограниченном оборудовании, таком как компьютер 1K ZX 80 или ZX 81. В BASIC вы бы

Let X = NOT PI

а не

LET X = 0

Так как числа были сохранены как 4-байтовые плавающие точки, последний занимает 2 байта больше, чем первая альтернатива NOT PI, где каждый из NOT и PI занимает один байт.

Ответ 6

Существует множество способов кодирования чисел во всех компьютерных архитектурах. При использовании 2 дополнения это всегда будет верно: ~0 == -1. С другой стороны, некоторые компьютеры используют 1 дополнение для кодирования отрицательных чисел, для которых приведенный выше пример неверен, потому что ~0 == -0. Yup, 1s-дополнение имеет отрицательный ноль, и поэтому он не очень интуитивно понятен.

Итак, на ваши вопросы

  • присваивается значение 0 для маскировки, поэтому все биты в маске равны 1 → создание mask & sth == sth
  • значение ~ 0 используется для того, чтобы все биты были равны 1 независимо от используемой платформы.
  • вы можете использовать -1 вместо ~ 0, если вы уверены, что ваша компьютерная платформа использует 2 кодировки номера дополнений.

Моя личная мысль - сделайте свой код настолько независимым от платформы, насколько сможете. Стоимость относительно небольшая, и код становится отказоустойчивым