-1

I'm writing a function that checks the Collatz conjecture. While doing this I also check if the number gets/is bigger than INT_MAX. But when i give a number bigger than INT_MAX as input, it just makes it INT_MAX. Because of this I can't check it. Is there a way around it?

the function:

#include <iostream>
#include <climits>

using namespace std;

bool limit = false;
int collatzCheck(int num) {
   limit = (num > INT_MAX || num <= 0);
   cout << "start: " << num << endl;
   int i = 0;
   while(num != 1 && !limit) {
      cout << ".." << endl;
      if(num%2 == 0) {
         num /= 2;
      } else {
         limit = (num > (INT_MAX-1)/3);
         if(!limit) num = num*3+1;
      }

      cout << num << endl;
      i++;
   }
   return i;
}

int main() {

   cout << "INT_MAX: " << INT_MAX << endl; 

   int num;
   cout << "num: ..";
   cin >> num;
   cout << "Iteraties: " << collatzCheck(num);
   if(limit) cout << ", INT_MAX is wel bereikt.." << endl;
   else cout << ", INT_MAX is niet bereikt!" << endl;

   return 0;
}
    
  • ```INT_MAX``` is ... well, the biggest number that an ```int``` could store. Change your variable type to ```long long``` – justANewb stands with Ukraine Oct 15 '21 at 09:15
  • Some Collatz sequences contain very large numbers before a power of 2 is attained (which is the final convergent path). The first option is to use an `unsigned` type where it's easier to detect overflow. But really though you need to use a library equipped for handling integers of unbounded size. – Bathsheba Oct 15 '21 at 09:22

1 Answers1

1

Proper way to do it is to calculate at compile time what is maximum value for which operation 3*x + 1 will not overflow integer type.

This is quite easy, just calculate (INT_MAX - 1) / 3 no big integers are needed.

using Integer = int;

bool nextCollatz(Integer& num) {
    if (num % 2 != 0) {
        constexpr auto max_val = std::numeric_limits<Integer>::max();
        constexpr auto max_safe_val = (max_val - 1) / 3;
        if (num > max_safe_val) return false;
        num = num * 3 + 1;
    } else {
        num /= 2;
    }
    return true;
}

int collatzCheck(Integer num) {
    std::cout << "start: " << num << '\n';
    int i = 0;
    while (num > 1) {
        if (!nextCollatz(num)) {
            std::cout << "integer limit reached!\n";
            break;
        }
        std::cout << num << '\n';
        i++;
    }
    return i;
}

https://godbolt.org/z/nce3s1Kd8

Marek R
  • 32,568
  • 6
  • 55
  • 140