# having trouble with a fraction program

James Novak

Greenhorn

Posts: 10

posted 7 years ago

Hi I've been working on this java program in class and I have to have two static methods that find the quotient of two fractions and the sum of two fractions. Everything in this program works up until the end. I have a feeling that I might be using the wrong kind of static method and i was wondering if some one could tell me how to make my code work. Both methods can only use two parameters each.

import java.util.Scanner;

/** new fraction data type, and that the faction may only be positive or zero,

*the fraction will always be in lowest terms

*

*/

public class Fraction

{

private int top; //numerator

private int bottom; //denominator

public Fraction()

{

top = 0;

bottom = 1;

}

/** The fraction () method is a default constructor that creates

* a default fraction that is equal to zero.

*

*/

public Fraction(int num, int denom)

{

if (denom == 0)

throw new IllegalArgumentException("Second argument " + denom + " cannot be zero.");

if (num < 0 || denom < 0)

throw new IllegalArgumentException("Both arguments, " + num + " and " + denom + ", cannot be negative.");

top = num;

bottom = denom;

reduce();

}

/** the method assign gives new values to the numerator and denominator

* of an existing Fraction

* @param num The value to assign to the numerator

* @param denom The value to assign to the denominator

* @exception IllegalArgumentException When the second argument is zero

* @exception IllegalArgumentException When either argument is negative

*/

public void assign(int num, int denom)

{

if (denom == 0)

throw new IllegalArgumentException("Second argument " + denom + " cannot be zero.");

if (num < 0 || denom < 0)

throw new IllegalArgumentException("Both arguments, " + num + " and " + denom + ", cannot be negative.");

top=num;

bottom=denom;

reduce();

}

/** The static multiply method returns the product

*of the two parameters

*@param f1 the first fraction to multiply

*@param f2 the second fraction to multiply

*@return The product of the f1 and f2

*/

public static Fraction multiply(Fraction f1, Fraction f2)

{

Fraction temp = new Fraction();

temp.top = f1.top * f2.top;

temp.bottom = f2.bottom * f2.bottom;

temp.reduce();

return temp;

}

private void reduce()

{

if (top == 0)

bottom = 1;

else

{

int min = (top < bottom ? top : bottom);

int gcd; //greatest common divisor

for (gcd = min; gcd > 1; --gcd)

if (top % gcd == 0 && bottom % gcd == 0)

break;

top = top / gcd;

bottom = bottom / gcd;

}

}

public void output()

{

if (top == 0)

{

System.out.print(0);

return;

}

if (top >= bottom)

{

System.out.print(top / bottom);

if (top % bottom != 0)

System.out.print(" and ");

}

if (top % bottom != 0)

System.out.print(top % bottom + "/" + bottom);

}

public void input()

{

Scanner keyboard = new Scanner(System.in);

String line = keyboard.nextLine();

int slash;

int total = line.length();

slash = -1;

for (int i = 0; i < total; ++i)

{

if (line.charAt(i) == '/')

{

slash = i;

break;

}

}

if (slash == -1)

{

System.out.println("ERROR in input");

}

else

{

String first = line.substring(0, slash);

String second = line.substring(slash + 1, total);

first = first.trim();

second = second.trim();

top = Integer.parseInt(first);

bottom = Integer.parseInt(second);

reduce();

}

}

public boolean equals(Fraction f2)

{

if (top == f2.top && bottom == f2.bottom)

return true;

else

return false;

}

public boolean lessThan(Fraction f2)

{

double temp1 = (double)top / bottom;

double temp2 = (double)f2.top / f2.bottom;

if (temp1 < temp2)

return true;

else

return false;

}

public boolean greaterThan(Fraction f2)

{

double temp1 = (double)top / bottom;

double temp2 = (double)f2.top / f2.bottom;

if (temp1 > temp2)

return true;

else

return false;

}

public static void divide(Fraction f2); //Error: Missing method body, or declare abstract

{

double quotientA = (double)top / bottom; //ERROR: cannot find symbol variable f1 or f2

double quotientB = (double)f2.top / f2.bottom; //ERROR: cannot find symbol variable f1 or f2

}

public static void addition(Fraction f2);

{

double newTop = (double)f2.bottom * top + f1.bottom * f2.top; //error cannot find symbol viarable f1 or f2

double newBottom = (double)bottom * f2.bottom; //error cannot find symbol variable f1 or f2

}

}

import java.util.Scanner;

/** new fraction data type, and that the faction may only be positive or zero,

*the fraction will always be in lowest terms

*

*/

public class Fraction

{

private int top; //numerator

private int bottom; //denominator

public Fraction()

{

top = 0;

bottom = 1;

}

/** The fraction () method is a default constructor that creates

* a default fraction that is equal to zero.

*

*/

public Fraction(int num, int denom)

{

if (denom == 0)

throw new IllegalArgumentException("Second argument " + denom + " cannot be zero.");

if (num < 0 || denom < 0)

throw new IllegalArgumentException("Both arguments, " + num + " and " + denom + ", cannot be negative.");

top = num;

bottom = denom;

reduce();

}

/** the method assign gives new values to the numerator and denominator

* of an existing Fraction

* @param num The value to assign to the numerator

* @param denom The value to assign to the denominator

* @exception IllegalArgumentException When the second argument is zero

* @exception IllegalArgumentException When either argument is negative

*/

public void assign(int num, int denom)

{

if (denom == 0)

throw new IllegalArgumentException("Second argument " + denom + " cannot be zero.");

if (num < 0 || denom < 0)

throw new IllegalArgumentException("Both arguments, " + num + " and " + denom + ", cannot be negative.");

top=num;

bottom=denom;

reduce();

}

/** The static multiply method returns the product

*of the two parameters

*@param f1 the first fraction to multiply

*@param f2 the second fraction to multiply

*@return The product of the f1 and f2

*/

public static Fraction multiply(Fraction f1, Fraction f2)

{

Fraction temp = new Fraction();

temp.top = f1.top * f2.top;

temp.bottom = f2.bottom * f2.bottom;

temp.reduce();

return temp;

}

private void reduce()

{

if (top == 0)

bottom = 1;

else

{

int min = (top < bottom ? top : bottom);

int gcd; //greatest common divisor

for (gcd = min; gcd > 1; --gcd)

if (top % gcd == 0 && bottom % gcd == 0)

break;

top = top / gcd;

bottom = bottom / gcd;

}

}

public void output()

{

if (top == 0)

{

System.out.print(0);

return;

}

if (top >= bottom)

{

System.out.print(top / bottom);

if (top % bottom != 0)

System.out.print(" and ");

}

if (top % bottom != 0)

System.out.print(top % bottom + "/" + bottom);

}

public void input()

{

Scanner keyboard = new Scanner(System.in);

String line = keyboard.nextLine();

int slash;

int total = line.length();

slash = -1;

for (int i = 0; i < total; ++i)

{

if (line.charAt(i) == '/')

{

slash = i;

break;

}

}

if (slash == -1)

{

System.out.println("ERROR in input");

}

else

{

String first = line.substring(0, slash);

String second = line.substring(slash + 1, total);

first = first.trim();

second = second.trim();

top = Integer.parseInt(first);

bottom = Integer.parseInt(second);

reduce();

}

}

public boolean equals(Fraction f2)

{

if (top == f2.top && bottom == f2.bottom)

return true;

else

return false;

}

public boolean lessThan(Fraction f2)

{

double temp1 = (double)top / bottom;

double temp2 = (double)f2.top / f2.bottom;

if (temp1 < temp2)

return true;

else

return false;

}

public boolean greaterThan(Fraction f2)

{

double temp1 = (double)top / bottom;

double temp2 = (double)f2.top / f2.bottom;

if (temp1 > temp2)

return true;

else

return false;

}

public static void divide(Fraction f2); //Error: Missing method body, or declare abstract

{

double quotientA = (double)top / bottom; //ERROR: cannot find symbol variable f1 or f2

double quotientB = (double)f2.top / f2.bottom; //ERROR: cannot find symbol variable f1 or f2

}

public static void addition(Fraction f2);

{

double newTop = (double)f2.bottom * top + f1.bottom * f2.top; //error cannot find symbol viarable f1 or f2

double newBottom = (double)bottom * f2.bottom; //error cannot find symbol variable f1 or f2

}

}

Ulf Dittmer

Rancher

Posts: 42968

73

posted 7 years ago

Welcome to JavaRanch.

There are extraneous semicolons in the addition and divide method declarations.

In the future, please UseCodeTags when posting code of an length. It's unnecessarily hard to read the code as it is, making it less likely that people will bother to do so. (I would have added those tags to your post, but the code is not indented at all...)

There are extraneous semicolons in the addition and divide method declarations.

In the future, please UseCodeTags when posting code of an length. It's unnecessarily hard to read the code as it is, making it less likely that people will bother to do so. (I would have added those tags to your post, but the code is not indented at all...)

posted 7 years ago

Here are some general tips...

1) Please use code tags to preserve your spacing. Code that isn't indented is VERY hard to read, and most folks here will just skip it - especially if it's more than about 10 lines. you can click the 'code' button above where you type your post to have them pop in, then paste your code between them.

2) please tell us EXACTLY what the problem is. You have basically said "this doesn't work". Does it compile? Does it die when you run it? Does it run, but give strange output?

3) If you get an error message, please post the EXACT contents of that message. Those messages give HUGE hints on what the problem is. If you don't get an error message, tell us what DOES happen, and what you EXPECTED to happen.

1) Please use code tags to preserve your spacing. Code that isn't indented is VERY hard to read, and most folks here will just skip it - especially if it's more than about 10 lines. you can click the 'code' button above where you type your post to have them pop in, then paste your code between them.

2) please tell us EXACTLY what the problem is. You have basically said "this doesn't work". Does it compile? Does it die when you run it? Does it run, but give strange output?

3) If you get an error message, please post the EXACT contents of that message. Those messages give HUGE hints on what the problem is. If you don't get an error message, tell us what DOES happen, and what you EXPECTED to happen.

There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors

James Novak

Greenhorn

Posts: 10

posted 7 years ago

Okay the exact problems are written in the bottom few lines of the program. What I am trying to do is get the integers top.f1, top.f2, and bottom.f1, and bottom.f2 to go through mathematical computations in the program. I get the errors in those static lines that they can't be found. I was able to get them to work in booleans, but I can't get them to function now.

James Novak

Greenhorn

Posts: 10

posted 7 years ago

These are the lines specifically, if this is easier. The errors that i get are next to them.

}

public static void divide(Fraction f2); //Error: Missing method body, or declare abstract

{

double quotientA = (double)top / bottom; //ERROR: cannot find symbol variable f1 or f2

double quotientB = (double)f2.top / f2.bottom; //ERROR: cannot find symbol variable f1 or f2

}

public static void addition(Fraction f2);

{

double newTop = (double)f2.bottom * top + f1.bottom * f2.top; //error cannot find symbol viarable f1 or f2

double newBottom = (double)bottom * f2.bottom; //error cannot find symbol variable f1 or f2

}

}

These are the lines specifically, if this is easier. The errors that i get are next to them.

Ulf Dittmer

Rancher

Posts: 42968

73

Campbell Ritchie

Sheriff

Posts: 50702

83

posted 7 years ago

You have already been told the errors are caused by too many ;s. In particular you mustn't put a ; after the name of a method and before its first {.

Why are you using

Why can't you have both numbers negative, and then call the fraction positive?Try this:Then you can use the Math.abs method and the - operator to set the signs of the two numbers.

You ought not to have so many static methods. You ought to have instance methods taking a single Fraction parameter, so you can writeI suggest you Google for "Euclid's algorithm" which is the oldest algorithm with a name. It is a much more elegant than what you have. It calculates the greatest common denominator for two numbersYour documentation comment is in the wrong place; it ought to

Find out the square root of the largest value an

[Pedantic mode]Don't call a constructor a method. You shouldn't write "fraction ()" in your comment. It reads "Fraction()". In fact, if you have the documentation comment in the right place, you would miss that bit out because it will link automatically.[/Pedantic mode, but such minor errors can lose you marks]

AgreeUlf Dittmer wrote:Welcome to JavaRanch.

So would I have.. . . (I would have added those tags to your post, but the code is not indented at all...)

You have already been told the errors are caused by too many ;s. In particular you mustn't put a ; after the name of a method and before its first {.

Why are you using

`double`arithmetic at all? A vulgar fraction has whole numbers as both its numerator and denominator. So you should never need floating point arithmetic in that class.

Why can't you have both numbers negative, and then call the fraction positive?Try this:Then you can use the Math.abs method and the - operator to set the signs of the two numbers.

You ought not to have so many static methods. You ought to have instance methods taking a single Fraction parameter, so you can writeI suggest you Google for "Euclid's algorithm" which is the oldest algorithm with a name. It is a much more elegant than what you have. It calculates the greatest common denominator for two numbersYour documentation comment is in the wrong place; it ought to

__precede__what it describes, not follow it.

Find out the square root of the largest value an

`int`can have then throw an Exception if the absolute values of top or bottom are greater than that square root (or if the absolute values remain resolutely < 0). That way you should be able to avoid an overflow error.

[Pedantic mode]Don't call a constructor a method. You shouldn't write "fraction ()" in your comment. It reads "Fraction()". In fact, if you have the documentation comment in the right place, you would miss that bit out because it will link automatically.[/Pedantic mode, but such minor errors can lose you marks]

James Novak

Greenhorn

Posts: 10

posted 7 years ago

I eneded up removing the excessive ;'s and now I'm getting the following errors for the bottom and top parts of my computation. The error reads something like

"non-static variable top cannot be referenced from a static context"

OR "non-static variable top bottom be referenced from a static context"

How can I get these non static variables to work in a static?

public static void divide(Fraction f2)

{

double quotientA = (double)top / bottom;

double quotientB = (double)f2.top / f2.bottom;

}

public static void addition(Fraction f2)

{

double newTop = (double)f2.bottom * top + bottom * f2.top;

double newBottom = (double)bottom * f2.bottom;

}

I eneded up removing the excessive ;'s and now I'm getting the following errors for the bottom and top parts of my computation. The error reads something like

"non-static variable top cannot be referenced from a static context"

OR "non-static variable top bottom be referenced from a static context"

How can I get these non static variables to work in a static?

Campbell Ritchie

Sheriff

Posts: 50702

83

James Novak

Greenhorn

Posts: 10

James Novak

Greenhorn

Posts: 10

posted 7 years ago

Okay I finally got it running without an error.

I have one other task to do.

I have a program titled FractionDriver.Java which outputs the various values

What I want to do is have it print out variables quotientA and quotientB at the bottom of the text.

I also want to print out the variables newTop / newBottom.

The error that I end up getting when I compile both the driver and the other program together is that the driver cannot find the variables. What should I do to fill this gap?

I have one other task to do.

I have a program titled FractionDriver.Java which outputs the various values

What I want to do is have it print out variables quotientA and quotientB at the bottom of the text.

I also want to print out the variables newTop / newBottom.

The error that I end up getting when I compile both the driver and the other program together is that the driver cannot find the variables. What should I do to fill this gap?

posted 7 years ago
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors

I changed your 'quote' tags to 'code' tags'.

Your variables newTop and newBottom don't exist by the time you want to print them. I would suggest you read up on 'scope', but basically, since you declare them inside the method addition(), once that method exists they are gone.

What you might want to to is have your addition method return a fraction itself, which would then have a 'top' and a 'bottom', then print those values.

Your variables newTop and newBottom don't exist by the time you want to print them. I would suggest you read up on 'scope', but basically, since you declare them inside the method addition(), once that method exists they are gone.

What you might want to to is have your addition method return a fraction itself, which would then have a 'top' and a 'bottom', then print those values.

Campbell Ritchie

Sheriff

Posts: 50702

83

posted 7 years ago

You can only get a Fraction back if the two values are whole numbers. I thought you had the algorithms worked out.Add: (n1*d2 + n2*d1)/(d1 * d2) Subtract: as add but with - for + Multiply: (n1 * n2)/(d1 * d2) Divide: (n1 * d2)/(n2 * d1) You get whole numbers which can be reduced with a greatest common denominator, as previously.

So, if you have to use static methods throughout, which looks like bad design to me, you use the following

So, if you have to use static methods throughout, which looks like bad design to me, you use the following

__pseudo__code and similarIf you always use the reduce() method in your constructor, then half that method is no longer required. Because all the values are passed as arguments, there will be no access to non-static variables in those methods.