The posted code has undefined behavior when now becomes larger than sqrt(INT_MAX), which is 46340 on 32-bit systems, because signed arithmetic overflow has undefined behavior. The result of computing now * now causing an overflow could be a negative number, or an exception or anything else, and computing now % cases with a negative now produces a number between -cases+1 and 0, which is what you observe.
If you use type long long for the intermediary result, the program will have defined behavior and output 22152025:
Note however that you make the assumption that int is large enough to represent 50000000, which the C Standard does not guarantee. For complete portability, you should use type long for now, cases and i.
Here is a modified version:
#include <stdio.h>
int main() {
long cases = 1000000L * 50;
long now = 1;
for (long i = 0; i < cases; i++) {
now++;
now = ((long long)now * now) % cases;
if (now < 0) {
break;
}
}
printf("%ld\n", now);
return 0;
}