HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMajor

"Longest Collatz sequence" in C slower than in Python 3

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thanslowersequencepythonlongestcollatz

Problem

This tight-looped memoization-less C solution to Project Euler's problem 14 seems efficient, but ran much slower than a similarly trivial Python 3 program. For the desired upper of 1000000, the C version ran practically forever, while Python 3 fairly quickly printed the correct result.

#include 

#define upper 1000000

int main() {
    int max = 1;
    int maxl = 1;

    for (int n = 1; n  maxl) {
                max = n;
                maxl = cl;
            }
        }
    }

    printf("%i\n", max);

    return 0;
}


Python 3:

#! /usr/bin/env python3

max = 1
maxl = 1

for n in range(1, 1000000):
    c = n
    cl = 1

    while c != 1:
        if c % 2 == 0:
            c /= 2
        else:
            c = 3 * c + 1
        cl += 1

        if cl > maxl:
            max = n
            maxl = cl

print(max)

Solution

Assuming int is 32 bit long on your system, an integer overflow occurs on c with upper = 1000000. The multiplication in c = 3 * c + 1 can cause c to grow quite large, eventually exceeding the \$2^{31}-1\$ upper limit of a 32-bit signed integer, and thus rolling over into negative values. Obviously, the algorithm does not work correctly for negative values of c, and gets stuck.

In Python on the other hand, none of this occurs, since it extends integers to arbitrary length automatically, and thus avoids overflows.

You can "postpone" this problem (i.e. make your program work for larger values of upper) by using larger (and unsigned) integer types, such as uint64_t from stdint.h for c up to \$2^{64}-1\$.

However, if you want your C code to work for arbitrarily large upper values, you'll have to use an external library for arbitrary-precision integers, such as GNU GMP (or roll your own, which is really not advisable except as an exercise). The disadvantage is slightly worse performance, which would likely be comparable to the Python version for such a simple and arithmetics-heavy program.

Context

StackExchange Code Review Q#157575, answer score: 26

Revisions (0)

No revisions yet.