Не (~) против отрицания(!)


#include <iostream>

using namespace std;
int main(int argc, char *argv[]) 
{
   int i=-5;
   while(~(i))
   {
      cout<<i;
      ++i;
   }

 }

Выход -5,-4,-3, -2. Разве он не должен выводить значения до -1?Почему только до -2. И пожалуйста, объясните мне разницу между операторами " не " и "отрицание".Когда я писал программу, они были источником ошибок.

while(i)

Я знаю, что условие цикла будет истинно для положительных и отрицательных i, кроме 0.

while(!i) vs while(~i)

Для каких значений 'i' выполняются два вышеприведенных цикла?

3   20  

3 ответа:

Когда i попадает в -1, значение ~i равно ~-1 или 0, поэтому цикл while перестает выполняться. Оператор ! работает, потому что он делает что-то совершенно другое; он приводит к 1 для 0 значений и 0 для всех других значений. ~ - побитовое отрицание.

Чуть подробнее:

  • ~ берет каждый бит в число и переключает его. Так, например, 100102 стал бы 011012
  • -1 - это все единицы в двоичном коде когда дополнение двойки целое число со знаком.
  • ~0b…11111111 - это 0.

Однако:

  • !0 является 1, !anythingElse is 0
  • -1 не является 0
  • !-1 все еще 0

И если вы действительно хотите, чтобы цикл включал i == -1, Просто используйте while (i) вместо while (~i).

Вы правы в том, что i == -1 является условием выхода: ваш цикл эквивалентен

int i=-5;
while(i != -1)
{
    cout<<i;
    ++i;
}
// i == -1 immediately after the loop

Когда пишется таким образом, должно быть понятно, почему -1 не печатается значение сначала печатается, а только затем увеличивается, поэтому -2 является последним значением, которое вы печатаете.

Оператор

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

' ~ ' - оператор, который : ~x = - x-1 а когда i = -1, то ~i = 0. если вам интересно значение ~i, вы можете просто распечатать их:

#include <iostream>

using namespace std;
int main(int argc, char *argv[]) 
{
   int i=-5;
   for (int i = -5; i <= 3; i++)
   {
    cout<<i<<"  "<<(~i)<<endl;
   }
 }

И тогда вы найдете: -5 4 -4 3 -3 2 -2 1 -1 0 0 -1 1 -2 2 -3 3 -4