1

Recently started learning C++ and i wrote a simple program that defines is the given number prime or not, and when the input is zero, it finishes. But i accidentally noticed that it creates an infinite loop when the input is somewhere between 2100000000 and 2200000000. I don't know why this happens, can you please explain to me?

#include <iostream>

using namespace std;

int number, i, k;

int main()
{
    do
    {
        cin >> number;
        if (number == 0)
            break;
        for (i = 2; i < round(sqrt(number)) + 1; i++)
            if (number % i == 0)
                k++;
        if ((number == 1) || (k > 0))
            cout << "This number is not prime\n";
        else
            cout << "This number is prime\n";
        k = 0;
        i = 0;
    } while (!(number == 0));
}
  • A signed int can hold values up to 2\*\*31-1, at which point it underflows to -2\*\*31. – Botje Oct 19 '20 at 17:00
  • 2
    This happens because you are using a variable of type int, which is signed by default. This means that the list of possible values for that number is between 2^0 and 2^31, since 1 bit is used for the sign. Any number that is beyond 2,147,483,647 will cause the range to go back to 0 and hence you will be in an endless loop. – Rahul Kadukar Oct 19 '20 at 17:01
  • 8
    @RahulKadukar No, signed int doesn't have wrap around on overflow, it's just UB. – cigien Oct 19 '20 at 17:02
  • Lots of assumptions about implementation defined behaviour here. – Etienne de Martel Oct 19 '20 at 17:24
  • What's your platform (Windows/whatever) and C++ version (e.g. C++03)? These details might be significant (not sure). Anyway, [this question with answer](https://stackoverflow.com/q/35898958/509868) may be relevant. – anatolyg Oct 19 '20 at 17:24
  • @anatolyg i'm using windows 10 pro and about c++ version... i don't exactly know what it is, but i downloaded visual studio a few days ago so it might be the latest version –  Oct 19 '20 at 17:31
  • *Debugging tips:* You have two loops in your code. Which one has decided to never end? Are we looking for a value of `round(sqrt(number)) + 1` that `i` never reaches, or are we looking for something that prevents `number` from being updated to zero? Can you simplify your example to have only one loop, yet still demonstrate the issue? – JaMiT Oct 19 '20 at 21:36

1 Answers1

0

The value overflows its type (int) which maximum value is 2147483647 and it results in Undefined Behaviour. If you need to accept large numbers as input you may have to use a long long. Additionally, why check if number equals 0 twice?

#include <iostream>
#include <math.h>

int main()
{
    while(true)
    {
        long long number;
        bool isPrime = true;
        std::cin >> number;
        if(number == 0)
            break;
        for (int i = 2; i < round(sqrt(number)) + 1; i++)
        {
            if (number % i == 0)
            {
                isPrime = false;
                break;
             }
        }

        if (isPrime)
             std::cout << "This number is prime\n"; //<== print this is this case
        else
             std::cout << "This number is not prime\n";
    }
    return 0;
}
Gary Strivin'
  • 908
  • 7
  • 20