Fleshing out BigFraction

Fleshing out BigFraction

Java Version We have created the bulk of the BigFraction class. You are going to add some nice little extras. They are specified in the methods here. Download this on the left; it should compile for you because all of the methods have been stubbed in.


import java.math.BigInteger;
public class BigFraction
{
    public static final BigFraction ONE;
    public static final BigFraction ZERO;
    public static final BigFraction HALF;
    static
    {
        ONE = BigFraction.valueOf(1, 1);
        ZERO = BigFraction.valueOf(0, 1);
        HALF = BigFraction.valueOf(1, 2);
    }
    private final BigInteger num;
    private final BigInteger denom;
    public BigFraction(BigInteger num, BigInteger denom)
    {
        if(denom.compareTo(BigInteger.ZERO) < 0)
        {
            num = num.negate();
            denom = denom.negate();
        }
        BigInteger d = num.gcd(denom);
        this.num = num.divide(d);
        this.denom = denom.divide(d);
    }
    public BigFraction(String num, String denom)
    {
        this(new BigInteger(num), new BigInteger(denom));
    }
    public static BigFraction valueOf(long num, long denom)
    {
        return new BigFraction(BigInteger.valueOf(num),
            BigInteger.valueOf(denom));
    }
    public String toString()
    {
        return String.format("%s/%s", num, denom);
    }
    public boolean equals(Object o)
    {
        if( !(o instanceof BigFraction))
        {
            return false;
        }
        BigFraction that = (BigFraction) o;
        return num.equals(that.num) && denom.equals(that.denom);
    }
    public BigFraction add(BigFraction that)
    {
        //  a/b + c/d = (ad + bc)/bd;
        BigInteger top = num.multiply(that.denom).add(denom.multiply(that.num));
        BigInteger bottom = denom.multiply(that.denom);
        return new BigFraction(top, bottom);
    }
    public BigFraction subtract(BigFraction that)
    {
        //  a/b - c/d = (ad - bc)/bd;
        BigInteger top = num.multiply(that.denom).subtract(denom.multiply(that.num));
        BigInteger bottom = denom.multiply(that.denom);
        return new BigFraction(top, bottom);
    }
    public BigFraction multiply(BigFraction that)
    {
        //  a/b * c/d = (ac)/bd;
        BigInteger top = num.multiply(that.num);
        BigInteger bottom = denom.multiply(that.denom);
        return new BigFraction(top, bottom);
    }
    public BigFraction divide(BigFraction that)
    {
        //  (a/b) / (c/d) = (ad)/bc;
        BigInteger top = num.multiply(that.denom);
        BigInteger bottom = denom.multiply(that.num);
        return new BigFraction(top, bottom);
    }
    /***************** Programming Exercises *******************/
    public BigFraction pow(int n)
    {   
        return null;
    }   
    //integer divide num/denom and round toward zero
    public BigInteger bigIntegerValue()
    {   
        return null;
    }   
    //return -this
    public BigFraction negate()
    {   
        return null;
    }   
    //return |this|
    public BigFraction abs()
    {   
        return null;
    }  
   //return a negative interger if this < that, a positive integer
    //if this > that, and 0 if this.equals(that).
    public int compareTo(BigFraction that)
    {
        return 0;
    }
    //return max(this, that)
    public BigFraction max(BigFraction that)
    {
        return null;
    }
    //return min(this, that)
    public BigFraction min(BigFraction that)
    {
        return null;
    }
   public static BigFraction harmonic(int n)
    {
        //return the nth harmonic number
        return null;
    }
    //annoying challenge problem.
    //return this big fraction as a double.  Sticky question:
    //how to deal with the infinite and zero cases.....
    //Note static members Double.NEGATIVE_INFINITY and Double.INFINITY.
    //test carefully. It's quite hard to get this right.
    public double doubleValue()
    {
        return 0;
    }
    public static void main(String[] args)
    {

        BigFraction f = BigFraction.valueOf(2,3);
        BigFraction g = BigFraction.valueOf(2, 4);
        BigFraction gag = BigFraction.valueOf(1,2);
        System.out.println(f.add(gag).equals(BigFraction.valueOf(7,6)));
        System.out.println(f.subtract(gag).equals(BigFraction.valueOf(1,6)));
        System.out.println(f.multiply(g).equals(BigFraction.valueOf(1,3)));
        System.out.println(f.divide(g).equals(BigFraction.valueOf(4,3)));
        System.out.printf("%s equals %s: %s\n", g, gag, g.equals(gag));
        BigFraction h = BigFraction.valueOf(7776, 1048576);
        System.out.println(f);
        System.out.println(g);
        System.out.println(h);
        System.out.println(f.add(g));
        BigFraction total = BigFraction.ZERO;
        BigFraction x = new BigFraction("1331", "726");
        System.out.println(x);
        for(int k = 1; k <= 100; k++)
        {
            total = total.add(BigFraction.valueOf(1,k));
        }
        System.out.println(total);
    }
}

Python Version


from number_theory import gcd
class BigFraction(object):
    def __init__(self, num, denom):
        if denom == 0:
            raise ValueError
        if denom < 0:
            num = -num
            denom = -denom
        d = gcd(num, denom)   
        self.num = num//d
        self.denom = denom//d
    #just like Java's toString
    def __str__(self):
        return f"{self.num}/{self.denom}"
    ## similar to Java's .equals method
    def __eq__(self, other):
        return self.num == other.num and self.denom == other.denom
    def __add__(self, other):
        top = self.num*other.denom + self.denom*other.num
        bottom =self.denom*other.denom 
        return BigFraction(top, bottom)
    def __sub__(self, other):
        top = self.num*other.denom - self.denom*other.num
        bottom =self.denom*other.denom 
        return BigFraction(top, bottom)
    def __mul__(self, other):
        top = self.num*other.num
        bottom = self.denom*other.denom
        return BigFraction(top, bottom)
    def __truediv__(self, other):
        top = self.num*other.denom
        bottom = self.denom*other.num
        return BigFraction(top, bottom)
    def __pow__(self, n):
        if type(n) != int:
            raise ValueError
        if n >= 0:
            return BigFraction (self.num**n, self.denom**n)
        else:
            n = -n
            return BigFraction (self.denom**n, self.num**n)
    def fractional_part(self):
        top = self.num % self.denom
        return BigFraction(top, self.denom)
    #find out what these are and implement them
    #appropriately
    def __gt__(self, other):
        pass
    def __lt__(self, other):
        pass
    def __ge__(self, other):
        pass
    def __le__(self, other):
        pass
    def __ne__(self, other):
        pass
    def negate(self):
        """returns -self"""
        pass
    def max(self, other):
        pass
    def min(self, other):
        pass
    def abs(self, other):
        pass
    def __int__(self):
        """truncate the factional part and return an integer."""
        pass
    def __float__(self):
        """super annoying challenge problem.  
        return a floating pooint representtaion of the value 
        of self."""
        pass
if __name__ == "__main__":
    #do the same tests here as you did in Java.
    f = BigFraction(1,2)
    g = BigFraction(2,4)
    h = BigFraction(1,-2)
    toid = BigFraction(1,3)
    print(f, g, h)
    print(f == g)
    print(f + toid)
    print(f - toid)
    print(f*toid)
    print(f/toid)
    print( (f + toid)**3)
    N = 1000
    out = BigFraction(0,1)
    #for k in range(1, N + 1):
        #out = out + BigFraction(1,k)
    #print(out)
    example = BigFraction(99,24);
    print(example.fractional_part())

def gcd(a,b):
    if a == 0 and b == 0:
        raise ValueError
    if a < 0:
        a = -a
    if b < 0:
        b = -b
    while b%a > 0:
        b, a = a, b%a
    return a
def smallest_factor(n):
    if n%2 == 0:
        return 2
    k = 3
    while k*k <= n:
        if n%k == 0:
            return k
        k += 2
    return n
def prime_factorization(n):
    out = []
    while n > 1:
        d = smallest_factor(n)
        print(d)
        n = n//d
        out.append(d)
    return out
def is_prime(n):
    if n%2 == 0:
        return 2
    k = 3
    while k*k <= n:
        if n%k == 0:
            return False
        k += 2
    return True
def primes_to(n):
    out = [2]
    k = 3
    while k <= n:
        j = 0
        while out[j]*out[j] <= k:
            if k%out[j] == 0:
                j += 1
                break
            j += 1
            out.append(k)
        k += 2
    return out

if __name__ == "__main__":
    #print(gcd(7776, 1048576))
    #print(gcd(95238908341908231432498324980875, 34904249809812494329625))
    #print(prime_factorization(1048575))
    #print(is_prime(1000009))
    #print(prime_factorization(1000009))
    #print(primes_to(10000))