Преобразование десятичной дроби в метод дробной формы (Java)
Я не могу найти простой метод, который преобразует десятичное значение в форму дроби. Мне нужен этот метод для использования в больших программах, поэтому метод должен быть передан двойное значение и вернуть строку.
РЕДАКТИРОВАТЬ: извините, новый здесь. Я просто хотел получить представление о том, как мне его создать. Примеры, которые я видел, назначают свои собственные значения для использования. Метод будет выглядеть так
public string convertype(double decimal){
(Statements)
return fraction;
}
2 ответа
public class Fraction {
private int numerator, denominator;
public Fraction(double decimal) {
String stringNumber = String.valueOf(decimal);
int numberDigitsDecimals = stringNumber.length() - 1 - stringNumber.indexOf('.');
int denominator = 1;
for (int i = 0; i < numberDigitsDecimals; i++) {
decimal *= 10;
denominator *= 10;
}
int numerator = (int) Math.round(decimal);
int greatestCommonFactor = greatestCommonFactor(numerator, denominator);
this.numerator = numerator / greatestCommonFactor;
this.denominator = denominator / greatestCommonFactor;
}
public String toString() {
return String.valueOf(numerator) + "/" + String.valueOf(denominator);
}
public static int greatestCommonFactor(int num, int denom) {
if (denom == 0) {
return num;
}
return greatestCommonFactor(denom, num % denom);
}
public static void main(String[] args) {
System.out.println(new Fraction(0.75));
}
}
public class NewClass {
public static void main(String[] args) {
System.out.println(convertype(0.75));
}
public static String convertype(double decimal){
int digitsAfterPoint = String.valueOf(decimal).length() - String.valueOf(decimal).indexOf('.')+1; // get the count of digits after the point // for example 0.75 has two digits
BigInteger numerator = BigInteger.valueOf((long)(decimal*Math.pow(10, digitsAfterPoint))); // multiply 0.75 with 10^2 to get 75
BigInteger denominator = BigInteger.valueOf((long)(Math.pow(10, digitsAfterPoint))); // 10^2 is your denominator
int gcd = numerator.gcd(denominator).intValue(); // calculate the greatest common divisor of numerator and denominator
if (gcd > 1 ){ // gcd(75,100) = 25
return String.valueOf(numerator.intValue()/gcd) +" / " + String.valueOf(denominator.intValue()/gcd); // return 75/25 / 100/25 = 3/4
}
else{
return String.valueOf(numerator) +" / " + String.valueOf(denominator); // if gcd = 1 which means nothing to simplify just return numerator / denominator
}
}
}
Прежде всего, если вы хотите преобразовать десятичное число, вам нужно знать состояние ситуации, прежде чем преобразовывать его, допустим, у вас есть 0,333333, число 3 повторяется бесконечно. Все мы знаем, что 0,333333 - это 1/3 . Некоторые думают, что умножение на количество цифр после запятой преобразует его. Это совершенно неверно. Это что-то связанное с математикой, другая ситуация - 0,25, возьмите числа после десятичной точки, разделите их на 100 и упростите их, что равно 1/4, совершенно верно!
Однако в математике у нас есть 3 ситуации для преобразования десятичного числа в дробь, я не буду их объяснять, потому что это займет много места и времени, я уже написал программу для этой задачи. Это код:
import java.math.BigDecimal;
import java.math.BigInteger;
public class Main {
static BigDecimal finalResult = new BigDecimal("0");
static boolean check(short[] checks) {
boolean isContinues = true;
int index = -1;
for (short ind : checks) {
index++;
if (ind==1) {
}
else if (ind==0) {
isContinues = false;
break;
}
else if (ind==-1) {
if (index==0) {
isContinues = false;
}
break;
}
}
return isContinues;
}
static int[] analyzeDecimal() { // will return int[3]
int[] analysis = new int[3];
int dot = finalResult.toString().indexOf(".");
String num = finalResult.toString();
int state = -1;
int firstPart = 0; // first part will be compared with each secondPart!
int secondPart = 0;
String part = ""; // without the dot
int index = 0; // index for every loop!
int loop = 6;
int originalLoop = loop;
int size = 0; // until six!
int ps = -1;
short[] checks = new short[] {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; // 10 compares for each part!
// length of checks is 10!
int continues = -1; // -1 means there is no continues part!
boolean stop = false;
while (true) { // while for size!
if (size!=6) {
while (true) { // we need to compare a part with a part!
// while for loop
// 6 loops, every loop will increase the compared part by 1!
if (loop!=-1) { // TODO : check every part with the increasing pos
firstPart = dot+1+(originalLoop-loop); // changed
try {
part = num.substring(firstPart, firstPart+(size+1));
}
catch (StringIndexOutOfBoundsException ex) {
break;
}
int partSize = part.length();
int afterDecimal = num.length()-(dot+1);
while (index!=checks.length &&
firstPart+partSize+index*partSize-(dot+1)<=afterDecimal) { // while for index!
secondPart = firstPart+partSize+index*partSize;
String comparedPart;
try {
comparedPart = num.substring(secondPart, secondPart+partSize);
}
catch (StringIndexOutOfBoundsException ex) {
break;
}
if (part.equals(comparedPart)) {
checks[index] = 1;
}
else {
checks[index] = 0;
}
index++;
}
index = 0;
if (check(checks)) {
stop = true;
continues = firstPart;
ps = partSize;
}
for (int i = 0 ; i!=10 ; i++) {
checks[i] = -1;
}
}
else { // finished!
break;
}
loop--;
if (stop) {
break;
}
}
loop = originalLoop;
size++;
if (stop) {
break;
}
}
else {
break;
}
}
if (continues==-1) {
state = 2;
}
else {
if (dot+1==continues) {
state = 1;
}
else {
state = 0;
}
}
analysis[0] = state;
analysis[1] = continues;
analysis[2] = ps;
return analysis;
}
static String convertToStandard() {
// determine the state first :
int[] analysis = analyzeDecimal();
int dot = finalResult.toString().indexOf('.')+1;
int continues = analysis[1];
int partSize = analysis[2]; // how many steps after the continues part
if (analysis[0]==0) { // constant + continues
String number = finalResult.toString().substring(0, continues+partSize);
int numOfConst = continues-dot;
int numOfDecimals = continues+partSize-dot;
int den = (int)(Math.pow(10, numOfDecimals)-Math.pow(10, numOfConst)); // (10^numOfDecimals)-(10^numOfConst);
int num;
int toSubtract = Integer.parseInt(number.substring(0, dot-1)+number.substring(dot, dot+numOfConst));
if (number.charAt(0)==0) {
num = Integer.parseInt(number.substring(dot));
}
else {
num = Integer.parseInt(number.replace(".", ""));
}
num -= toSubtract;
return simplify(num, den);
}
else if (analysis[0]==1) { // continues
int num, den;
// we always have to subtract by only one x!
String n = finalResult.toString().substring(0, dot+partSize).replace(".", "");
num = Integer.parseInt(n);
den = nines(partSize);
int toSubtract = Integer.parseInt(finalResult.toString().substring(0, dot-1));
num -= toSubtract;
return simplify(num, den);
}
else if (analysis[0]==2) { // constant
partSize = finalResult.toString().length()-dot;
int num = Integer.parseInt(finalResult.toString().replace(".", ""));
int den = (int)Math.pow(10, partSize);
return simplify(num, den);
}
else {
System.out.println("[Error] State is not determined!");
}
return "STATE NOT DETERMINED!";
}
static String simplify(int num, int den) {
BigInteger n1 = new BigInteger(Integer.toString(num));
BigInteger n2 = new BigInteger(Integer.toString(den));
BigInteger GCD = n1.gcd(n2);
String number = Integer.toString(num/GCD.intValue())+"/"+Integer.toString(den/GCD.intValue());
return number;
}
static int nines(int n) {
StringBuilder result = new StringBuilder();
while (n!=0) {
n--;
result.append("9");
}
return Integer.parseInt(result.toString());
}
public static void main(String[] args) {
finalResult = new BigDecimal("1.222222");
}
}
Приведенная выше программа даст вам оптимальный результат с высокой точностью. Все, что вам нужно сделать, это изменить переменную finalResult в функции main.