重复小数到分数计算器的java.lang.StringIndexOutOfBoundsException

时间:2017-11-20 15:54:39

标签: java string substring

我是java的新手,我正在尝试编写一个采用重复小数并将其转换为分数的方法。它需要输入(双十进制不重复,int数字的尾随数字重复),即(0.3,1)将是0.3333 ....和(1.583,2)将是1.5838383 .... 我收到此错误,我似乎无法找出问题所在。当前输入为(10.3,1)

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1967)
at Fraction.<init>(Fraction.java:44)
at Main.main(Main.java:12)
exited with non-zero status

继承我的代码:

public Fraction(double t, int repeating)
{
    double decRight = t, decLeft = t;
    String rStr = "0000000000000000000" + String.valueOf(decRight);
    String lStr = "0000000000000000000" + String.valueOf(decLeft);
    int count1 = 0, count2 = 0, rDecIndex = rStr.indexOf("."), lDecIndex = lStr.indexOf(".");
    while(!lStr.substring(lDecIndex - repeating,lDecIndex).replace("\\.","").equals(lStr)) //this is line 44, the problem area
    {
        decLeft *= 10;
        count1++;
        lStr = "0000000000000000000" + String.valueOf(decLeft);
        lDecIndex = lStr.indexOf(".");
    }
    while(!rStr.substring(rDecIndex,repeating).replace("\\.","").equals(rStr))
    {
        decRight*= 10;
        count2++;
        rStr = "0000000000000000000" + String.valueOf(decRight);
        rDecIndex = rStr.indexOf(".");
    }
    top = (int)(decLeft - decRight);
    bot = (int)(Math.pow(10,count1) - Math.pow(10,count2));
    reduce();
}

错误在子字符串中。

2 个答案:

答案 0 :(得分:0)

根据评论,您需要一个带有重复小数的整数和一个整数,其中包含重复部分之前的内容。

我认为你已经解决了这个问题,而不仅仅是使用子字符串来获取你想要的字符串部分。

/**
 * Code By Loren CC-BY
 */
public class test
{
    public static void fraction(String t, int repeating)
    {
        int bot = 0;
        for (int i = 0; i < repeating; i++) {
            bot *= 10;
            bot += 9;
        }
        String dString = t;
        // Get the repeating part of the string as an int
        int repeat = Integer.valueOf(dString.substring(dString.length()-repeating));
        // Get the string from in front of the repeating number
        String front = dString.substring(0, dString.length()-repeating);
        // Convert it to a double
        double before = Double.valueOf(front);
        // Debugging information
        System.out.println("Before: "+ front+" " +before+" "+dString.substring(dString.length()-repeating));

        // Turn the before string into an int and compute the denominator such that 1.5 could become 15/10
        int count = 0;
        while (Math.abs(Math.round(before) - before) > 0.000001) {
            before *= 10;
            count++;
        }
        // Print debugging information
        System.out.println(count);
        // Compute the top of the combined fraction
        int top = ((int)before)*bot+repeat;

        bot = (int)Math.pow(10,count) * bot;
        System.out.println(top+" "+bot);
        // TODO: Reduce fraction
    }

    public static void main(String[] args) {
        fraction("0.3",1);
        fraction("1.580",2);
        fraction("0.34",1);
        fraction("0.34",2);
    }
}

注意:你不能传入双1.580,因为它作为一个字符串是1.58而不是1.580,因为0被省略,这会弄乱函数。

答案 1 :(得分:0)

对于将重复小数转换为分数,您可以尝试以下方法:

import java.math.BigInteger;

public class ConvertRepeatingNumbersToFraction {

    public static void main(String[] args) {
        convertToFraction("0.3",1);
        convertToFraction("1.580",2);
        convertToFraction("0.16",1);
        convertToFraction("0.34",2);
        convertToFraction("0.42",2);
        convertToFraction("0.34",1);
    }



    private static void convertToFraction(String x, int numOfRepeatingDigits) {

        int denominator = 0;

        for (int i = 0; i < numOfRepeatingDigits; i++) {
            denominator = denominator * 10 + 9;
        }

        int repeatingNumber = Integer.valueOf(x.substring(x.length() - numOfRepeatingDigits));
        double numerator = Double.valueOf(x.substring(0, x.length() - numOfRepeatingDigits));

        int count = 0;
        if (numerator % 1 != 0) {
            numerator = numerator * 10;
            count++;
        }

        numerator = numerator * denominator + repeatingNumber;
        denominator = (int) Math.pow(10, count) * denominator;

        int[] fraction = reduce((int)numerator, denominator);
        System.out.println(fraction[0] + "/" + fraction[1]);
    }

    private static int[] reduce(int num, int den) {
        // common divisor
        int commonDivisor = BigInteger.valueOf(num).gcd(BigInteger.valueOf(den)).intValue();
        return new int[]{ num / commonDivisor, den / commonDivisor };
    }
}

我检查了http://onlinecalculators.brainmeasures.com/Numbers/RecurringDecimalNumbertoFraction.aspx上的测试号码,结果是一样的。

希望有所帮助:)