Task: First 9 prime Fibonacci number


C++: #include <chrono>
#include <iostream>
#include <sstream>
#include <utility>
#include <primesieve.hpp>
#include <gmpxx.h>

using big_int = mpz_class;

bool is_probably_prime(const big_int& n) {
    return mpz_probab_prime_p(n.get_mpz_t(), 30) != 0;
}

class prime_fibonacci_generator {
public:
    prime_fibonacci_generator();
    std::pair<uint64_t, big_int> next();
private:
    big_int next_fibonacci();
    primesieve::iterator p_;
    big_int f0_ = 0;
    big_int f1_ = 1;
    uint64_t n_ = 0;
};

prime_fibonacci_generator::prime_fibonacci_generator() {
    for (int i = 0; i < 2; ++i)
        p_.next_prime();
}

std::pair<uint64_t, big_int> prime_fibonacci_generator::next() {
    for (;;) {
        if (n_ > 4) {
            uint64_t p = p_.next_prime();
            for (; p > n_; ++n_)
                next_fibonacci();
        }
        ++n_;
        big_int f = next_fibonacci();
        if (is_probably_prime(f))
            return {n_ - 1, f};
    }
}

big_int prime_fibonacci_generator::next_fibonacci() {
    big_int result = f0_;
    big_int f = f0_ + f1_;
    f0_ = f1_;
    f1_ = f;
    return result;
}

std::string to_string(const big_int& n) {
    std::string str = n.get_str();
    if (str.size() > 40) {
        std::ostringstream os;
        os << str.substr(0, 20) << "..." << str.substr(str.size() - 20) << " ("
           << str.size() << " digits)";
        return os.str();
    }
    return str;
}

int main() {
    auto start = std::chrono::high_resolution_clock::now();
    prime_fibonacci_generator gen;
    for (int i = 1; i <= 26; ++i) {
        auto [n, f] = gen.next();
        std::cout << i << ": F(" << n << ") = " << to_string(f) << '\n';
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> ms(finish - start);
    std::cout << "elapsed time: " << ms.count() << " seconds\n";
}








COBOL:        IDENTIFICATION DIVISION.
       PROGRAM-ID. PRIME-FIBONACCI.
       
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 FIBONACCI-VARS.
          03 FIB                PIC 9(6).
          03 FIB-B              PIC 9(6).
          03 FIB-C              PIC 9(6).
          03 FIB-OUT            PIC Z(5)9.
       01 PRIME-VARS.   
          03 PRIME-FLAG         PIC X.
             88 PRIME           VALUE 'X'.
          03 DSOR               PIC 9(4).
          03 DSOR-SQ            PIC 9(6).
          03 DIV-RSLT           PIC 9(6)V9(3).
          03 FILLER             REDEFINES DIV-RSLT.
             05 FILLER          PIC 9(6).
             05 FILLER          PIC 9(3).
                88 DIVISIBLE    VALUE ZERO.
          
       PROCEDURE DIVISION.
       BEGIN.
           MOVE 1 TO FIB, FIB-B.
           PERFORM FIND-PRIME-FIBONACCI 9 TIMES.
           STOP RUN.
       
       FIND-PRIME-FIBONACCI.
           ADD FIB, FIB-B GIVING FIB-C.
           MOVE FIB-B TO FIB.
           MOVE FIB-C TO FIB-B.
           PERFORM CHECK-PRIME.
           IF NOT PRIME, GO TO FIND-PRIME-FIBONACCI.
           MOVE FIB TO FIB-OUT.
           DISPLAY FIB-OUT.
       
       CHECK-PRIME SECTION.
       BEGIN.
           MOVE SPACE TO PRIME-FLAG.
           IF FIB IS LESS THAN 5, GO TO TRIVIAL-PRIME.
           DIVIDE FIB BY 2 GIVING DIV-RSLT.
           IF DIVISIBLE, GO TO DONE.
           DIVIDE FIB BY 3 GIVING DIV-RSLT.
           IF DIVISIBLE, GO TO DONE.
           MOVE 5 TO DSOR.
           MOVE 25 TO DSOR-SQ.
           MOVE 'X' TO PRIME-FLAG.
           PERFORM TEST-DIVISOR 
           UNTIL NOT PRIME OR DSOR-SQ IS GREATER THAN FIB.
           GO TO DONE.
           
       TEST-DIVISOR.
           DIVIDE FIB BY DSOR GIVING DIV-RSLT.
           IF DIVISIBLE, MOVE SPACE TO PRIME-FLAG.
           ADD 2 TO DSOR.
           DIVIDE FIB BY DSOR GIVING DIV-RSLT.
           IF DIVISIBLE, MOVE SPACE TO PRIME-FLAG.
           ADD 4 TO DSOR.
           MULTIPLY DSOR BY DSOR GIVING DSOR-SQ.
       
       TRIVIAL-PRIME.
           IF FIB IS EQUAL TO 2 OR 3, MOVE 'X' TO PRIME-FLAG.
       DONE.
           EXIT.