12 Replies - 1765 Views - Last Post: 10 April 2011 - 09:19 PM Rate Topic: -----

#1 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Fraction to Floating Point to Fraction

Posted 10 April 2011 - 05:57 PM

I am writing a program the takes a fraction, converts it into a floating point number, and then prints out a fraction that hopefully matches the input, but in simplified form. I have checked for repeating patterns, but I feel like there is an easier way to do this. Any help would be appreciated.

import java.util.*;

public class RepeatingDecimal {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		// User enters a fraction y/x.
		System.out.print("Enter a fraction: ");
		String fraction = in.nextLine();
		// Store the numerator and the denominator.
		int vinculum = fraction.indexOf('/');
		int numerator = Integer.parseInt(fraction.substring(0, vinculum));
		int denominator = Integer.parseInt(fraction.substring(vinculum + 1,
				fraction.length()));
		// Divide the 2 numbers to find the floating point number.
		double input = (double) numerator / denominator;
		// Store the whole number for later.
		int whole = (int) Math.floor(input);
		// Find the decimal portion of the floating point number.
		double decimal = input - whole;
		// Convert the decimal to a string and remove the '0.'
		String decStr = Double.toString(decimal);
		int point = decStr.indexOf('.');
		decStr = decStr.substring(point + 1, decStr.length());
		// 'values[]' store all the decimal places.
		int[] values = new int[decStr.length()];
		// Add the decimal places to the array.
		for (int i = 0; i < decStr.length(); i++) {
			values[i] = Integer.parseInt(decStr.substring(i, i + 1));
		}
		// Initialize the numerator & denominator outputs.
		int numer = 0;
		int denom = 1;
		// If decimal is too long, check for a pattern
		if (values.length == 16) {
			// Check for 1/3 : 0.333
			if (values[0] == values[1] && values[1] == values[2]
					&& values[2] == values[3]) {
				numer = values[0];
				denom = 9;
			} // check for 1/11 : 0.0909
			else if (values[0] == values[2] && values[1] == values[3]) {
				numer = values[0] * 10 + values[1];
				denom = 99;
			} // check for 115/333 : 0.345345
			else if (values[0] == values[3] && values[1] == values[4]
					&& values[2] == values[5]) {
				numer = values[0] * 100 + values[1] * 10 + values[2];
				denom = 999;
			} // If no pattern is found:
			else {
				int limit = 8;
				for (int i = 0; i < limit; i++) {
					numer += values[i] * (int) Math.pow(10, limit - i);
				}
				denom = (int) Math.pow(10, limit);
			}
		}
		// if decimal is rational
		else {
			for (int i = 0; i < values.length; i++) {
				numer += values[i] * (int) Math.pow(10, values.length - i);
			}
			denom = (int) Math.pow(10, values.length + 1);
		}
		// Make the fraction improper
		numer += whole * denom;
		// Find the gcd of the numerator and denominator.
		int gcd = gcd(numer, denom);
		// Divide the numerator and denominator by the gcd.
		numer /= gcd;
		denom /= gcd;
		// Print out the answer and hope it matches the input(simplified)
		System.out.printf("%d/%d", numer, denom);
	}

	// Recursive Euclidean algorithm to find gcd
	private static int gcd(int a, int B)/> {
		if (b == 0)
			return a;
		else
			return gcd(b, a % B)/>;
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: Fraction to Floating Point to Fraction

#2 softwareEngineer()  Icon User is offline

  • D.I.C Head

Reputation: -28
  • View blog
  • Posts: 247
  • Joined: 08-April 11

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 06:01 PM

I think I found something here.

Your code was hurting my eyes, so I wasn't sure if your code was close to this or not.
Was This Post Helpful? 0
  • +
  • -

#3 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 06:12 PM

View PostsoftwareEngineer(), on 10 April 2011 - 06:01 PM, said:

I think I found something here.

Your code was hurting my eyes, so I wasn't sure if your code was close to this or not.


Sorry I lack methods, but I CAN convert decimal to fraction, the problem is I have to search for MOST patterns for repeating decimals. I was wondering if there was an easier way?

1/3 = 0.33333333 => 3/9 = 1/3
1/7 = 0.142857 => 142857/999999 = 1/7
Was This Post Helpful? 0
  • +
  • -

#4 softwareEngineer()  Icon User is offline

  • D.I.C Head

Reputation: -28
  • View blog
  • Posts: 247
  • Joined: 08-April 11

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 06:14 PM

I'm afraid I am not understanding your question.

Are you saying that you have to keep listing out every single repeating decimal there is?

I think I know how to fix that.
Was This Post Helpful? 0
  • +
  • -

#5 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 07:06 PM

View PostsoftwareEngineer(), on 10 April 2011 - 06:14 PM, said:

I'm afraid I am not understanding your question.

Are you saying that you have to keep listing out every single repeating decimal there is?

I think I know how to fix that.


I organized my code a little better: Is there any way to simplify my checkPattern() function??? That is my question.

import java.util.*;

public class FloatToFraction {

	public int inputNumerator;
	public int inputDenominator;
	private int outputNumerator;
	private int outputDenominator;
	private int wholeNumber;
	private double floatingPoint;
	public int[] values;

	public FloatToFraction() {
		inputNumerator = 0;
		inputDenominator = 1;
		outputNumerator = 0;
		outputDenominator = 1;
		wholeNumber = 0;
		floatingPoint = 0.00;
	}

	public static void main(String[] args) {
		FloatToFraction f = new FloatToFraction();
		Scanner in = new Scanner(System.in);
		// User enters a fraction y/x.
		System.out.print("Enter a fraction: ");
		String frac = in.nextLine();
		f.fraction(frac);
		// Print out the answer and hope it matches the input(simplified)
		System.out.printf("%d/%d", f.getNumerator(), f.getDenominator());
	}

	// Store the numerator and the denominator.
	private void fraction(String frac) {
		int vinculum = frac.indexOf('/');
		inputNumerator = Integer.parseInt(frac.substring(0, vinculum));
		inputDenominator = Integer.parseInt(frac.substring(vinculum + 1,
				frac.length()));
		simplify();
	}

	// Divide the 2 numbers to find the floating point number.
	public void setFloat() {
		floatingPoint = (double) inputNumerator / inputDenominator;
		floatingPoint -= (int) Math.floor(floatingPoint);
	}

	public double getFloat() {
		return floatingPoint;
	}

	// Store the whole number for later.
	public void setWhole() {
		wholeNumber = (int) Math.floor(floatingPoint);
	}

	public int getWhole() {
		return wholeNumber;
	}

	public void setNumerator(int numerator) {
		numerator = outputNumerator;
	}

	public int getNumerator() {
		return outputNumerator;
	}

	public void setDenominator(int denominator) {
		denominator = outputDenominator;
	}

	public int getDenominator() {
		return outputDenominator;
	}

	public void decimalPlaces() {
		setWhole(); // Set the whole number
		setFloat(); // Set floating point numbers
		// Convert the decimal to a string and remove the '0.'
		String decStr = Double.toString(getFloat());
		int point = decStr.indexOf('.');
		decStr = decStr.substring(point + 1, decStr.length());
		// 'values[]' store all the decimal places.
		values = new int[decStr.length()];
		// Add the decimal places to the array.
		for (int i = 0; i < decStr.length(); i++) {
			values[i] = Integer.parseInt(decStr.substring(i, i + 1));
		}
	}

	public void setOutput(int numerator, int denominator) {
		outputNumerator = numerator;
		outputDenominator = denominator;
	}

	// If decimal is too long, check for a pattern
	public void checkPattern() {
		decimalPlaces();
		if (values.length == 16) {
			// Check for 1/3 : 0.333
			if (values[0] == values[1] && values[1] == values[2]
					&& values[2] == values[3]) {
				setOutput(values[0], 9);
			} // check for 1/11 : 0.0909
			else if (values[0] == values[2] && values[1] == values[3]) {
				setOutput(values[0] * 10 + values[1], 99);
			} // check for 115/333 : 0.345345
			else if (values[0] == values[3] && values[1] == values[4]
					&& values[2] == values[5]) {
				setOutput(values[0] * 100 + values[1] * 10 + values[2], 999);
			} // If no pattern is found:
			else {
				int numerator = 0;
				int limit = 8;
				for (int i = 0; i < limit; i++) {
					numerator += values[i] * (int) Math.pow(10, limit - i);
				}
				setOutput(numerator, (int) Math.pow(10, limit));
			}
		}
		// if decimal is rational
		else {
			int numerator = 0;
			for (int i = 0; i < values.length; i++) {
				numerator += values[i] * (int) Math.pow(10, values.length - i);
			}
			setOutput(numerator, (int) Math.pow(10, values.length + 1));
		}
	}

	public void simplify() {
		checkPattern();
		outputNumerator += getWhole() * outputDenominator;
		// Find the gcd of the numerator and denominator.
		int gcd = gcd(outputNumerator, outputDenominator);
		// Divide the numerator and denominator by the gcd.
		outputNumerator /= gcd;
		outputDenominator /= gcd;
	}

	// Recursive Euclidean algorithm to find gcd
	private int gcd(int a, int B)/> {
		if (b == 0)
			return a;
		else
			return gcd(b, a % B)/>;
	}
}


This post has been edited by x68zeppelin80x: 10 April 2011 - 07:08 PM

Was This Post Helpful? 0
  • +
  • -

#6 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 07:26 PM

Next I'll have to check for 0.1234512345 which = 12345/99999...
The further I check the more code I write :(

if (values[0] == values[1] && values[1] == values[2] && values[2] == values[3]) {
	setOutput(values[0], 9);
} // check for 1/11 : 0.0909
else if (values[0] == values[2] && values[1] == values[3]) {
	setOutput(values[0] * 10 + values[1], 99);
} // check for 115/333 : 0.345345
else if (values[0] == values[3] && values[1] == values[4] && values[2] == values[5]) {
	setOutput(values[0] * 100 + values[1] * 10 + values[2], 999);
} // check for 1234/9999 = 0.12341234
else if (values[0] == values[4] && values[1] == values[5] && values[2] == values[6] && values[3] == values[7]) {
	setOutput(values[0] * 1000 + values[1] * 100 + values[2] * 10 + values[3], 9999);
} // If no pattern is found:


Was This Post Helpful? 0
  • +
  • -

#7 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8328
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 07:44 PM

I would use the "brute" force to solve that problem
You will need to specify the maximum denominator to test to the method

	public static void main(String[] args) {
		toFract(0.3333, 20);
		toFract(0.5, 10);
	}

       public static void toFract(double val, int maxDenom) {
       int bestNum = 1, bestDen = 1;
       double diff = 999999.9;
	   
       for(int denom = 1; denom < maxDenom; ++denom) {
    	   for(int num = 1; num < denom; ++num) {
    		   double value = (double) num / (double) denom;
    		   double delta = Math.abs(val - value);
    		   if(delta < diff) {
    			   diff = delta;
    			   bestNum = num;
    			   bestDen = denom;
    		   }
    	   }
       }
       int div = gcd(bestNum, bestDen);
       bestNum /= div;
       bestDen /= div;
       System.out.println(val + " = " + bestNum + " / " + bestDen);		
    }


Was This Post Helpful? 1
  • +
  • -

#8 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 08:02 PM

View Postpbl, on 10 April 2011 - 07:44 PM, said:

I would use the "brute" force to solve that problem
You will need to specify the maximum denominator to test to the method


Thanks, maybe the max denom can be determined by a ratio of the decimal length...
Was This Post Helpful? 0
  • +
  • -

#9 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8328
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 08:22 PM

View Postx68zeppelin80x, on 10 April 2011 - 10:02 PM, said:

Thanks, maybe the max denom can be determined by a ratio of the decimal length...

I don't think there is a relation here
1 / 3 = .33333333333333333
You should just go to 3 as max denom
Was This Post Helpful? 0
  • +
  • -

#10 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 08:54 PM

View Postpbl, on 10 April 2011 - 08:22 PM, said:

View Postx68zeppelin80x, on 10 April 2011 - 10:02 PM, said:

Thanks, maybe the max denom can be determined by a ratio of the decimal length...

I don't think there is a relation here
1 / 3 = .33333333333333333
You should just go to 3 as max denom


There is a relation, but it is not the best solution

public String decimalToString(double decimal) {
	String decStr = Double.toString(decimal);
	int point = decStr.indexOf('.');
	return decStr.substring(point + 1, decStr.length());
}

int maxDenom = (int)(Math.pow(10, decimalToString(0.4325).length()) + 1);



Since 0.4325 or 4325 is 4 chars long, then the maxDenom = ((10 ^ 4) + 1) or 10001, but this will take a long time.

On the other hand, if you have a pattern like 0.123123123, then the maxDenom = 999.
Was This Post Helpful? 0
  • +
  • -

#11 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8328
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 09:02 PM

Good point :^:
Actually, won't take that much time unless you still run an old IBM 380 :)

and my algorithm can be optimize in many point
you can start the inner loop at a higher value doing an approximation based on the double value -1:
- if you are looking for .3333 and denom is 10 no need to start at 1 you can start at 10.0 / .3333 - 1 or something like it
- you can break out of the loop if num / denom is really < then value (just have to remember the last approximation)
Was This Post Helpful? 2
  • +
  • -

#12 x68zeppelin80x  Icon User is offline

  • D.I.C Addict

Reputation: 130
  • View blog
  • Posts: 576
  • Joined: 07-March 09

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 09:11 PM

View Postpbl, on 10 April 2011 - 09:02 PM, said:

Good point :^:
Actually, won't take that much time unless you still run an old IBM 380 :)

and my algorithm can be optimize in many point
you can start the inner loop at a higher value doing an approximation based on the double value -1:
- if you are looking for .3333 and denom is 10 no need to start at 1 you can start at 10.0 / .3333 - 1 or something like it
- you can break out of the loop if num / denom is really < then value (just have to remember the last approximation)


Thank you for your input. I noticed I made a catastrophic mistake...
I am making the fraction improper too early...

Example:

5.33333333 => 5 3/9 = 48/9 CAN BE: 5 1/3 = 16/3

The larger the number the more I have to simplify...
Was This Post Helpful? 0
  • +
  • -

#13 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8328
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Fraction to Floating Point to Fraction

Posted 10 April 2011 - 09:19 PM

Have fun
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1