0
#include <iostream>
using namespace std;

// example low level C code big integer data type
typedef int* mpz_t;

bool check = false;

void mpz_init(mpz_t &x) {
    if (check) cout << "initing\n";
    x = new int;
    *x = 0;
}

void mpz_set(mpz_t &dest, const mpz_t &src) {
    if (check) cout << "setting\n";
    *dest = *src;
}

void mpz_set_si(mpz_t &dest, const int &val) {
    if (check) cout << "setting si\n";
    *dest = val;
}

void mpz_add(mpz_t &res, const mpz_t &a, const mpz_t &b) {
    *res = (*a) + (*b);
}

void mpz_mul(mpz_t &res, const mpz_t &a, const mpz_t &b) {
    *res = (*a) * (*b);
}

/**********************************/
// class with canonical form
class bignum
{
public:
    mpz_t value;

public:
    bignum() {
        mpz_init(value);
    }

    bignum(int val) {
        mpz_init(value);
        mpz_set_si(value, val);
    }

    bignum(const bignum &b) {
        mpz_init(value);
        mpz_set(value, b.value);
    }

    ~bignum() {
        //clear value
    }

    bignum& operator = (const bignum &b) {
        if (this != &b) mpz_set(value, b.value);
        return (*this);
    }

    bignum operator + (const bignum &b) {
        bignum res;
        mpz_add(res.value, value, b.value);
        return res;
    }

    bignum operator * (const bignum &b) {
        bignum res;
        mpz_mul(res.value, value, b.value);
        return res;
    }
};

int main()
{
    bignum a = 5, b = 10, c = 15;
    bignum res = 0;
    check = true;
    res = (a+b)*c + a;
    cout << (*res.value) << "\n";
    return 0;
}

I have to wrap highly-optimized low-level C code into a C++ class. When evaluating an expression res = (a+b)*c + a, a temporary object tmp1 is created for a+b, tmp2 for (a+b)*c, tmp3 for (a+b)*c + a, and then res = tmp3;

This seems very wasteful because it takes 3 mpz_init() for temporary variables that will just disappear. Is there anyway I can do to reduce the cost of this?

Thank you.

Huy Le
  • 1,439
  • 4
  • 19
  • 1
    Are you aware that the C++ interface to libGMP uses [expression templates](https://en.wikipedia.org/wiki/Expression_templates) to do just that? The [documentation](https://gmplib.org/manual/C_002b_002b-Interface-General.html#C_002b_002b-Interface-General) implies it: "An important feature of the implementation is that an expression like a=b+c results in a single call to the corresponding mpz_add, without using a temporary for the b+c part. " – Botje Apr 15 '20 at 09:12
  • 1
    Does this answer your question? [C++ Expression Templates](https://stackoverflow.com/questions/2598579/c-expression-templates) – Botje Apr 15 '20 at 09:12
  • @Botje using gmp++ instantly solve this problem but then I wouldn't learn how to solve it by myself :D Thanks. I'll read about C++ Expresion Template – Huy Le Apr 15 '20 at 09:14
  • @Botje if you can write a comment showing how to perform res = a+b or res = a*b in a single step, it would be very appreciated – Huy Le Apr 15 '20 at 09:24
  • See the article linked from [this answer](https://stackoverflow.com/a/2598640/1548468) or read gmpxx.h – Botje Apr 15 '20 at 11:14

0 Answers0