What I need to convert decimal to fractions. It is easy to convert to 10's feet.
1.5 => 15/10
This can do via this code:
public class Rational {
private int num, denom;
public Rational(double d) {
String s = String.valueOf(d);
int digitsDec = s.length() - 1 - s.indexOf('.');
int denom = 1;
for (int i = 0; i < digitsDec; i++) {
d *= 10;
denom *= 10;
}
int num = (int) Math.round(d);
this.num = num;
this.denom = denom;
}
public Rational(int num, int denom) {
this.num = num;
this.denom = denom;
}
public String toString() {
return String.valueOf(num) + "/" + String.valueOf(denom);
}
public static void main(String[] args) {
System.out.println(new Rational(1.5));
}
}
But what I want is
1.5 => 3/2
and I don't get how to proceed. My question is not a duplication. Because other related question is C#. This is java.
You should find the greatest common divisor of the resulted numbers and divide the numerator and denominator by it.
Here is one way to do it:
public class Rational {
private int num, denom;
public Rational(double d) {
String s = String.valueOf(d);
int digitsDec = s.length() - 1 - s.indexOf('.');
int denom = 1;
for (int i = 0; i < digitsDec; i++) {
d *= 10;
denom *= 10;
}
int num = (int) Math.round(d);
int g = gcd(num, denom);
this.num = num / g;
this.denom = denom /g;
}
public Rational(int num, int denom) {
this.num = num;
this.denom = denom;
}
public String toString() {
return String.valueOf(num) + "/" + String.valueOf(denom);
}
public static int gcd(int num, int denom) {
....
}
public static void main(String[] args) {
System.out.println(new Rational(1.5));
}
}
static private String convertDecimalToFraction(double x){
if (x < 0){
return "-" + convertDecimalToFraction(-x);
}
double tolerance = 1.0E-6;
double h1=1; double h2=0;
double k1=0; double k2=1;
double b = x;
do {
double a = Math.floor(b);
double aux = h1; h1 = a*h1+h2; h2 = aux;
aux = k1; k1 = a*k1+k2; k2 = aux;
b = 1/(b-a);
} while (Math.abs(x-h1/k1) > x*tolerance);
return h1+"/"+k1;
}
I got this answer from here. All I had to do is convert his answer to java.
Given double x >= 0, int p, int q, find p/q as closest approximation:
- iterate on q from 1 upwards, determine p above and below; check deviations
So (not tested):
public static Rational toFraction(double x) {
// Approximate x with p/q.
final double eps = 0.000_001;
int pfound = (int) Math.round(x);
int qfound = 1;
double errorfound = Math.abs(x - pfound);
for (int q = 2; q < 100 && error > eps; ++q) {
int p = (int) (x * q);
for (int i = 0; i < 2; ++i) { // below and above x
double error = Math.abs(x - ((double) p / q));
if (error < errorfound) {
pfound = p;
qfound = q;
errorfound = error;
}
++p;
}
}
return new Rational(pfound, qfound);
}
You could try it for Math.PI and E.
Here is a simple algorythme :
numerato = 1.5
denominator = 1;
while (!isInterger(numerator*denominator))
do
denominator++;
done
return numerator*denominator + '/' + denominator
// => 3/2
You just have to implement it in java + implement the isInteger(i)
where i
is a float
.
Including the method to find highest common factor and modifying toString method, solves your question i suppose.
public String toString() {
int hcf = findHighestCommonFactor(num, denom);
return (String.valueOf(num/hcf) + "/" + String.valueOf(denom/hcf));
}
private int findHighestCommonFactor(int num, int denom) {
if (denom == 0) {
return num;
}
return findHighestCommonFactor(denom, num % denom);
}
Not only for the decimal number 1.5
, for all you can use the following steps:
Find Number of decimal digits:
double d = 1.5050;//Example I used
double d1 = 1;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
System.out.println(decimalPlaces);//4
Then convert to integer:
static int ipower(int base, int exp) {
int result = 1; for (int i = 1; i <= exp; i++) { result *= base; } return result; }
//using the method
int i = (int) (d*ipower(10, decimalPlaces));
int i1 = (int) (d1*ipower(10, decimalPlaces));
System.out.println("i=" + i + " i1 =" +i1);//i=1505 i1 =1000
Then find highest common factor
private static int commonFactor(int num, int divisor) {
if (divisor == 0) { return num; } return commonFactor(divisor, num % divisor); }
//using common factor
int commonfactor = commonFactor(i, i1);
System.out.println(commonfactor);//5
Finally print results:
System.out.println(i/commonfactor + "/" + i1/commonfactor);//301/200
Here you can find:
public static void main(String[] args) {
double d = 1.5050;
double d1 = 1;
String text = Double.toString(Math.abs(d));
int integerPlaces = text.indexOf('.');
int decimalPlaces = text.length() - integerPlaces - 1;
System.out.println(decimalPlaces);
System.out.println(ipower(10, decimalPlaces));
int i = (int) (d*ipower(10, decimalPlaces));
int i1 = (int) (d1*ipower(10, decimalPlaces));
System.out.println("i=" + i + " i1 =" +i1);
int commonfactor = commonFactor(i, i1);
System.out.println(commonfactor);
System.out.println(i/commonfactor + "/" + i1/commonfactor);
}
static int ipower(int base, int exp) {
int result = 1;
for (int i = 1; i <= exp; i++) {
result *= base;
}
return result;
}
private static int commonFactor(int num, int divisor) {
if (divisor == 0) {
return num;
}
return commonFactor(divisor, num % divisor);
}
I tried adding this as an edit, but it was denied. This answer builds off of @Hristo93's answer but finishes the gcd method:
public class DecimalToFraction {
private int numerator, denominator;
public Rational(double decimal) {
String string = String.valueOf(decimal);
int digitsDec = string.length() - 1 - s.indexOf('.');
int denominator = 1;
for (int i = 0; i < digitsDec; i++) {
decimal *= 10;
denominator *= 10;
}
int numerator = (int) Math.round(decimal);
int gcd = gcd(numerator, denominator);
this.numerator = numerator / gcd;
this.denominator = denominator /gcd;
}
public static int gcd(int numerator, int denom) {
return denominator == 0 ? numerator : gcm(denominator, numerator % denominator);
}
public String toString() {
return String.valueOf(numerator) + "/" + String.valueOf(denominator);
}
public static void main(String[] args) {
System.out.println(new Rational(1.5));
}
}
I prepared a solution for this question. Maybe it's look like primitive but working. I tested many decimal number. At least it can converting 1.5 to 3/2 :)
public String kesirliYap(Double sayi){
String[] a=payPaydaVer(sayi);
return a[0]+"/"+a[1];
}
public String[] payPaydaVer(Double sayi){
long pay;
long payda;
DecimalFormat df=new DecimalFormat("#");
df.setRoundingMode(RoundingMode.FLOOR);
String metin=sayi.toString();
int virguldenSonra=(metin.length() -metin.indexOf("."))-1;
double payyda=Math.pow(10,virguldenSonra);
double payy=payyda*sayi;
String pays=df.format(payy);
String paydas=df.format(payyda);
pay=Long.valueOf(pays);
payda=Long.valueOf(paydas);
String[] kesir=sadelestir(pay,payda).split(",");
return kesir;
}
private String sadelestir(Long pay,Long payda){
DecimalFormat df=new DecimalFormat("#");
df.setRoundingMode(RoundingMode.FLOOR);
Long a=pay<payda ? pay : payda;
String b = "",c = "";
int sayac=0;
for(double i = a;i>1;i--){
double payy=pay/i;
double paydaa=payda/i;
String spay=df.format(payy);
String spayda=df.format(paydaa);
Long lpay=Long.valueOf(spay);
Long lpayda=Long.valueOf(spayda);
if((payy-lpay)==0&&(paydaa-lpayda)==0){
b=df.format(pay/i);
c=df.format(payda/i);
sayac++;
break;
}
}
return sayac>0 ? b+","+c:pay+","+payda;
}
来源:https://stackoverflow.com/questions/31585931/how-to-convert-decimal-to-fractions