Convert float to string fraction representation

In Java, I am trying to find a way to convert a float number to a fractional part string. For example:

float num = 1.33333; String numStr = Convert(num); // Should return "1 1/3" float num2 = 1.333; String numStr2 = Convert(num2); // Should also return "1 1/3" float num3 = 0.5; String numStr3 = Convert(num3); // Should return "1/2" float num4 = 2.25; String numStr4 = Convert(num4); // Should return "2 1/4" 

Any ideas how to do this in Java?

+8
java string floating-point fractions
source share
6 answers

The easiest way is to use trial and error.

 public static String toFraction(double d, int factor) { StringBuilder sb = new StringBuilder(); if (d < 0) { sb.append('-'); d = -d; } long l = (long) d; if (l != 0) sb.append(l); d -= l; double error = Math.abs(d); int bestDenominator = 1; for(int i=2;i<=factor;i++) { double error2 = Math.abs(d - (double) Math.round(d * i) / i); if (error2 < error) { error = error2; bestDenominator = i; } } if (bestDenominator > 1) sb.append(' ').append(Math.round(d * bestDenominator)).append('/') .append(bestDenominator); return sb.toString(); } public static void main(String... args) { System.out.println(toFraction(1.3333, 1000)); System.out.println(toFraction(1.1428, 1000)); for(int i=1;i<100000000;i*=10) { System.out.println("PI "+i+": "+toFraction(3.1415926535897932385, i)); } } 

prints

 1 1/3 1 1/7 PI 1: 3 PI 10: 3 1/7 PI 100: 3 14/99 PI 1000: 3 16/113 PI 10000: 3 16/113 PI 100000: 3 14093/99532 PI 1000000: 3 140914/995207 PI 10000000: 3 244252/1725033 
+9
source share

Look at the continued fractions. This allows you to determine the denominator and fraction with a given accuracy.

For Pi, you can get 22/7 or 355/113 depending on when you decide to stop.

+1
source share

This can help:

http://www.merriampark.com/fractions.htm

Otherwise, you'll need a way to tell Convert () how far you want to do something. Maybe it's a maximally reduced demonizer or something like that. Thus, you will get “1 1/3” for the first two two examples above, not “1 33333/100000” for the first and “1 333/1000” for the second.

0
source share

Extract the fractional part of the number (for example, ((int) 0.5 + 1) - 0.5 , and then divide the result by the result ( 1 / 0.5 ). You will get the fraction denominator. Then move the float to int and you will get the integer part. Then combine both .

This is a simple solution and will only work if the numerator of the fraction is 1.

 double n = 1.2f; int denominator = 1 / (Math.abs(n - (int) n - 0.0001)); //- 0.0001 so the division doesn't get affected by the float point aproximated representation int units = (int) n; int numerator = units * denominator + 1; System.out.println("" + numerator + "/" + denominator); //6/5 System.out.println("" + units + " 1/" + denominator); //1 1/5 
0
source share

Suppose you have "0.1234567" and then count the number of numbers after the decimal point (which is 7). then multiply the number with 10 ^ 7, now you have "1234567".

divide 1234567 over 10 ^ 7. Then simplify the fraction using the GCD of two numbers.

 0.1234567 * 10000000 = 1234567 => 1234567 / 10000000 => System.out.println(1234567 / gcd(1234567,10000000) + "/" + 10000000/gcd(1234567,10000000)); 
0
source share

Changed the FOR loop to break the loop when the best denominator is already defined.

if (error2 == 0) break;

 public static String toFraction(double d, int factor) { StringBuilder sb = new StringBuilder(); if (d < 0) { sb.append('-'); d = -d; } long l = (long) d; if (l != 0) sb.append(l); d -= l; double error = Math.abs(d); int bestDenominator = 1; for(int i=2;i<=factor;i++) { double error2 = Math.abs(d - (double) Math.round(d * i) / i); if (error2 < error) { error = error2; bestDenominator = i; if (error2 == 0) break; } } if (bestDenominator > 1) sb.append(' ').append(Math.round(d * bestDenominator)).append('/') .append(bestDenominator); return sb.toString(); } public static void main(String... args) { System.out.println(toFraction(1.3333, 1000)); System.out.println(toFraction(1.1428, 1000)); for(int i=1;i<100000000;i*=10) { System.out.println("PI "+i+": "+toFraction(3.1415926535897932385, i)); } } 
0
source share

All Articles