Working with fractions (C++)

Programming, for all ages and all languages.
Post Reply
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Working with fractions (C++)

Post 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.
This was supposed to be a cool signature...
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Working with fractions (C++)

Post 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.
Every good solution is obvious once you've found it.
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Re: Working with fractions (C++)

Post 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.
This was supposed to be a cool signature...
Post Reply