Page 1 of 1

Working with fractions (C++)

Posted: Mon Oct 06, 2008 10:24 am
by Zacariaz
Well, I have allready "solved" this problem, however, it's not very pretty, so if any of you have suggestions, comments or whatever, I'd be glad to hear them.

By now you probably have a question or two, but the code should explain it:

Code: Select all

#include <vector>

struct F { // this should explain it self, numerator, denominetor...
    long n, d;
};

class Fraction {

    std::vector<unsigned short> P; // refer to constructor.

    F Factorize(F f) { // for factorizing the fractions.

        for(short i = 0; P[i] <= f.n && P[i] <= f.d; i++) {

            if(!(f.n % P[i]) && !(f.d % P[i])) {

                f.n /= P[i];
                f.d /= P[i];
                i = -1;

            };

        }

        return f;

    }

public:

    Fraction() { // generating list of primes for factorization.

        P.push_back(2);

        for(unsigned short n = 3; n < 0x3fff; n += 2) {

            for(unsigned short i = 1; P[i] * P[i] <= n; i++) {

                if(!(n % P[i])) {

                    i = 0;
                    n += 2;
                    if(n > 0x3fff) break;

                }

            }

            P.push_back(n);

        }

    }

    F Add(F a, F b) { // From here it should be pretty self explaining.

        a.n = (a.n*b.d)+(b.n*a.d);
        a.d *= b.d;
        return Factorize(a);

    }

    F Sub(F a, F b) {

        a.n = (a.n*b.d)-(b.n*a.d);
        a.d *= b.d;
        return Factorize(a);

    }

    F Mul(F a, F b) {

        a.n *= b.n;
        a.d *= b.d;
        return Factorize(a);

    }

    F Div(F a, F b) {

        a.n *= b.d;
        a.d *= b.n;
        return Factorize(a);

    }

};
It's not very well testet, as it is somewhat complicated to use, but it should work.
I know of course that a lot of uptimization can be done, but though I also welcome such suggestions, this is not the apparent problem.

It just seems too complicated and messy.


Regards.

edit:

I just discovered a problem regarding natagive numbers. fx. 1/6 - 1/2 = -4/12 where the result should be -1 over 3. I can only imagine that (a % b) don't work as expected if negative numbers are involved. I have though and implimented a solution, but again it is very very ugly.

Code: Select all

    F Factorize(F f) { // for factorizing the fractions.
        bool sign[2] = {0};
        if(f.n < 0) {
            sign[0] = 1;
            f.n *= -1;
        }
        if(f.d < 0) {
            sign[1] = 1;
            f.d *= -1;
        }
        for(short i = 0; P[i] <= f.n && P[i] <= f.d; i++) {

            if(!(f.n % P[i]) && !(f.d % P[i])) {

                f.n /= P[i];
                f.d /= P[i];
                i = -1;

            };

        }
        if(sign[0]) f.n *=-1;
        if(sign[1]) f.d *=-1;

        return f;

    }
On a site note, I never suspected this much trouble when I first started this half an hour ago, but I guess I'm simply not experienced enough, which comes as no surprise.

Re: Working with fractions (C++)

Posted: Tue Oct 07, 2008 1:41 am
by Solar
As usual, I don't delve into what the code actually does (not enough time), but focus on language / general programming issues.

Immediate thought #1: That's a perfect example for a good place to use operator overloading...

Thought #2: Have you checked your assumptions on how '%' works for negative numbers with a short test program, or have you looked it up in the language standard?

I seem to remember that the definition of '%' for negatives (at least in earlier language definitions) could be understood in two different ways.

Re: Working with fractions (C++)

Posted: Tue Oct 07, 2008 6:56 am
by Zacariaz
I have checked the % operator and it seemed that it worked as it should both with negative and positive numbers. Obiously I was mistaken, or I have made some stupid error which I have been unable to find.