странное поведение unsigned long long int в цикле - PullRequest
1 голос
/ 25 июня 2019

Пока я решал эту проблему на хакерранке, я заметил странную вещь в цикле for. Сначала позвольте мне показать пример кода:

#include <bits/stdc++.h>
using namespace std;
#define modVal 1000000007;

int main() {
    for(long long int i=2;i>=0;--i){
        cout<<"here: "<<i<<endl;
    }
}

вход: 123

вывод: здесь: 2 здесь: 1 здесь: 0 164

Теперь, когда я изменяю long long int на unsigned long long int в цикле for для инициализации переменной i. Переменная i инициализируется с помощью 18446744073709551615. Почему это происходит?

Ответы [ 3 ]

6 голосов
/ 25 июня 2019

Если переменная не подписана, i >= 0 равен всегда true. Так что твой цикл никогда не заканчивается. Когда я добираюсь до 0, следующий - делает i 0xFFFFFFFFFFFFFFFF (десятичное 18446744073709551615).

3 голосов
/ 25 июня 2019

Числа без знака, как следует из названия, не принимают значения со знаком.Поэтому, когда я = -1, на самом деле это 0xFFFFFFFFFFFFFFFF (18446744073709551615 в десятичном формате).

Вы можете сами убедиться в этом с измененной программой.

 #include <bits/stdc++.h>
 using namespace std;
 #define modVal 1000000007;

 int main() {
    for(unsigned long long int i=2;i>=0;--i){
         cout<<"here: "<<i<<endl;
       if(i > 3)
          return 0;
   }
 }
3 голосов
/ 25 июня 2019

Поскольку неподписанные типы не могут быть отрицательными, попытка установить их в отрицательное значение заставит их обернуться и вместо этого удерживать std::numeric_limits<T>::max() - abs(value) + 1, где T - тип, а value - значение ниже 0.

В вашем цикле, когда i достигает 0, условие i >= 0 все еще выполняется и, таким образом, оно уменьшается до -1, но это невозможно для неподписанных типов, как объяснено выше, и, таким образом, цикл никогда не завершится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...