【问题标题】:How to convert decimal to fractions?如何将小数转换为分数?
【发布时间】:2015-10-13 16:10:56
【问题描述】:

我需要将小数转换为分数。转换为 10 英尺很容易。

1.5 => 15/10

这可以通过以下代码实现:

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));
    }
}

但我想要的是

1.5 => 3/2

我不知道如何继续。 我的问题不是重复。因为其他相关问题是 C#。这是java。

【问题讨论】:

  • 你的意思是 1.53/2 吗?
  • 你如何将你的构造函数复制到一个也接受所需分母并简单地除以它的构造函数上?
  • 既然你可以做 1.5 -> 15/10,那么只需取 15 和 10,找到最大公约数,然后使用它。
  • @nadir.. 很高兴你能理解。问题是我不知道该怎么做:)

标签: java decimal fractions


【解决方案1】:
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;
}

我从here 得到了这个答案。我所要做的就是将他的答案转换为 java。

【讨论】:

  • 工作但你能解释一下
  • 查看链接。它解释了一切。
  • 这真是太棒了!!
  • 但它返回 0.5 的 1.0/2.0。如何删除这些零。可能 int xx=(int) h1; int yy=(int) k1;返回 xx+"/"+k1;
【解决方案2】:

你应该找到结果数的最大公约数,然后除以它的分子和分母。

这是一种方法:

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));
    }
}

【讨论】:

  • 什么是 gcd()?我看不懂那个方法?
  • @pippilongstocking best-common-divisor 在您的语言中可能存在相同的缩写。所以 2/4 减少到 1/2。有很大帮助。如果您将字段设置为final,则您将拥有一个不可变的类,并且乘法等会创建一个新的约简分数。
  • gsd() 中有什么?
【解决方案3】:

给定 double x >= 0, int p, int q,找到 p/q 作为最接近的近似值:

  • 从1向上迭代q,确定p上下;检查偏差

所以(未测试):

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);
}

你可以试试 Math.PI 和 E。

【讨论】:

  • 这是迄今为止最好的答案!
【解决方案4】:

这是一个简单的算法:

numerato = 1.5
denominator = 1;

while (!isInterger(numerator*denominator))
do
    denominator++;
done

return numerator*denominator + '/' + denominator


// => 3/2

您只需要在 java 中实现它 + 实现 isInteger(i),其中 ifloat

【讨论】:

  • 我不确定这是否有效?分子在循环迭代期间不会改变,所以 isInteger 永远不会返回 true?我也认为会有比线性搜索更有效的算法。
  • 是的,这是一个错字:我编辑了while (!isInterger(numerator*denominator))
  • 这有点令人困惑。你能解释一下吗?请问?
【解决方案5】:

包括找到最大公因数的方法和修改 toString 方法,我想解决了你的问题。

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);
    }

【讨论】:

    【解决方案6】:

    不只是十进制数1.5,大家可以使用以下步骤:

    1. 查找小数位数:

      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

    2. 然后转成整数:

      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

    3. 然后求最大公因数

      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

    1. 最后打印结果:

      System.out.println(i/commonfactor + "/" + i1/commonfactor);//301/200

    您可以在这里找到:

      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);
        }
    

    【讨论】:

      【解决方案7】:

      我尝试将其添加为编辑,但被拒绝。这个答案建立在@Hristo93 的answer 之上,但完成了 gcd 方法:

      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));
          }
      }
      

      【讨论】:

        【解决方案8】:

        我为这个问题准备了一个解决方案。也许它看起来像原始但有效。我测试了许多十进制数。至少它可以将 1.5 转换为 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;
        }
        

        【讨论】:

        • 不客气
        【解决方案9】:

        首先,如果你想转换一个十进制数,你需要在转换之前知道情况的状态,假设你有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");
                System.out.println(convertToStandard());
            }
        }
        

        上述程序将为您提供高精度的最佳结果。您所要做的就是更改 main 函数中的 finalResult 变量。

        【讨论】:

          【解决方案10】:

          检查一下这个简单的实现,我没有使用任何 GCD 或其他东西,相反,我已经为分子设置了逻辑并继续递增直到逻辑不满足。

          public static void main(String[] args) {
              Scanner scan = new Scanner(System.in);
              
              System.out.println("Enter the decimal number:");
              double d = scan.nextDouble();
              
              int denom = 1;
              boolean b = true;
              while(b) {
                  String[] s = String.valueOf(d * denom).split("\\.");
                  if(s[0].equals(String.valueOf((int)(d * denom))) && s[1].equals("0")) {
                      break;
                  }
                  denom++;
              }
              
              if(denom == 1) {
                  System.out.println("Input a decimal number");
              }
              else {
                  System.out.print("Fraction: ");
                  System.out.print((int)(d*denom)+"/"+denom);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-07-09
            • 1970-01-01
            • 2023-03-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多