Download cpp source code

#include <QtMath>
#include <QVector>

#include "GoldbachWorker.h"

GoldbachWorker::GoldbachWorker(long long number, QVector<QString>& results, QObject *parent)
    : QThread{parent}
    , number{number}
    , results{results}
{
}

void GoldbachWorker::run()
{
    long long sumCount = this->calculate(this->number);
    emit calculationDone(sumCount);
}

long long GoldbachWorker::calculate(long long number)
{
    if ( number < 4 || number == 5 ) return 0;
    return number % 2 == 0 ? calculateEvenGoldbach(number) : calculateOddGoldbach(number);
}

long long GoldbachWorker::calculateEvenGoldbach(long long number)
{
    long long results = 0;
    for ( long long a = 2; a < number && this->isInterruptionRequested() == false; ++a )
    {
        emit this->progressUpdated( static_cast<int>(100LL * a / (number - 1)) );

        if ( ! isPrime(a) ) continue;
        long long b = number - a;
        if ( b >= a && isPrime(b) )
            this->results.append( tr("%1: %2 + %3").arg(++results).arg(a).arg(b) );
    }
    return results;
}

long long GoldbachWorker::calculateOddGoldbach(long long number)
{
    long long results = 0;
    for ( long long a = 2; a < number; ++a )
    {
        emit this->progressUpdated( static_cast<int>(100LL * a / (number - 1)) );

        if ( ! isPrime(a) ) continue;
        for ( long long b = a; b < number; ++b )
        {
            if ( this->isInterruptionRequested() )
                return results;

            if ( ! isPrime(b) ) continue;
            long long c = number - a - b;
            if ( c >= b && isPrime(c) )
                this->results.append( tr("%1: %2 + %3 + %4").arg(++results).arg(a).arg(b).arg(c) );
        }
    }
    return results;
}

bool GoldbachWorker::isPrime(long long number)
{
    if ( number < 2 ) return false;

    long long last = static_cast<long long>( qSqrt( number) );
    for ( long long i = 2; i <= last; ++i )
        if ( number % i == 0 )
            return false;

    return true;
}