java 试图将一个混合分数从一个命令行参数转换为一个双精度数

eagi6jfj  于 2023-10-14  发布在  Java
关注(0)|答案(3)|浏览(67)

我试图将一个混合分数(如“1 1/2”)从一个命令行参数转换为一个小数(如1.5)。这是我的Java课本上的一个问题,我遇到了麻烦。这是我目前所知道的。它适用于像“1/2”这样的分数,并将其转换为0.5,但不是混合数

class Fractions {
    static public void main(String[] args) {
        double output = 0;
        String input =args[0];
        String[] inputArray = input.split(" ");
        if (input.contains("/")) { //checks if it has a slash
            if (inputArray.length == 2) { // this is to check if it is a mixed number but it          fails to check
                double integer = Double.parseDouble(inputArray[0]);
                String[] numbers = input.split("/");
                double top = Double.parseDouble(numbers[0]);
                double bottom = Double.parseDouble(numbers[1]);
                output = integer + top/bottom;
            } else { //If it is not a mixed number and a fraction it correctly prints the    double form
                String[] numbers = input.split("/");
                double top = Double.parseDouble(numbers[0]);
                double bottom = Double.parseDouble(numbers[1]);
                output = top/bottom;
            }
        } else { //otherwise it turns the input into a double 
            output = Double.parseDouble(input); 
        } 
        System.out.println(output); //prints the number as a double
    }
}
ovfsdjhp

ovfsdjhp1#

“这是我到目前为止所拥有的。它适用于像“1/2”这样的分数,并将其转换为0.5,但不是混合数。
numbers 赋值过程中,input 值解析不正确。

String[] numbers = input.split("/");

这将产生 “1 1”“2”
这里有一个例子。

String s = args[0];
int i = 0, n, d, a;
if ((a = s.indexOf(' ')) != -1) {
    i = Integer.parseInt(s.substring(0, a));
    s = s.substring(a + 1).trim();
}
a = s.indexOf('/');
n = Integer.parseInt(s.substring(0, a));
d = Integer.parseInt(s.substring(a + 1));
double x = i + ((double) n / d);

此外,您还可以使用 * BigDecimal * 类。

String s = args[0];
int a;
BigDecimal i = BigDecimal.ZERO, n, d, x;
if ((a = s.indexOf(' ')) != -1) {
    i = new BigDecimal(s.substring(0, a));
    s = s.substring(a + 1).trim();
}
a = s.indexOf('/');
n = new BigDecimal(s.substring(0, a));
d = new BigDecimal(s.substring(a + 1));
x = i.add(n.divide(d, 5, RoundingMode.HALF_UP));

相反,如果你需要将值转换回分数。

String f(double x) {
    String s = String.valueOf(x);
    s = s.substring(s.indexOf('.') + 1);
    int n = Integer.parseInt(s);
    if (n == 0) return String.valueOf((int) x);
    class GCF {
        static int of(int a, int b) {
            if (b == 0) return a;
            return of(b, a % b);
        }
    }
    int d = (int) Math.pow(10, s.length()),
        gcf = GCF.of(n, d),
        i = (int) x;
    if (gcf != 0) {
        n /= gcf;
        d /= gcf;
    }
    if (i != 0) return "%d %d/%d".formatted(i, n, d);
    return "%d/%d".formatted(n, d);
}

下面是一个示例用法。

f(0.125)   1/8
f(0.25)    1/4
f(0.375)   3/8
f(0.5)     1/2
f(0.625)   5/8
f(0.75)    3/4
f(0.875)   7/8
f(1.0)     1
f(1.125)   1 1/8
f(1.25)    1 1/4
f(1.375)   1 3/8
f(1.5)     1 1/2
f(1.625)   1 5/8
f(1.75)    1 3/4
f(1.875)   1 7/8
ngynwnxp

ngynwnxp2#

问题出在这一行:

String[] numbers = input.split("/");
                   ^^^^^

你拆分了input变量,而不是混合值的第二部分:inputArray[1]。正确的代码应该是:

String[] numbers = inputArray[1].split("/");
wd2eg0qa

wd2eg0qa3#

我相信你已经意识到了这一点,但我想我会把它扔在无论如何。由于整数和实际分数之间存在空格,因此应将命令行参数括在引号内,例如:myapp.jar "1 1/2"
正如您已经意识到的,您对命令行参数(FractionString)的解析对于您想要做的事情并不完全正确。下面是一个runnable,演示了如何做到这一点。它有点冗长,但是,它也进行了大量的验证,并显示(在我看来)如何在使用时最小化问题。请务必阅读代码中的所有注解:

public class FractionToDoubleDemo {

    
    public static void main(String[] args) {
        /* App started this way to avoid the need for statics
           unless we really want them:        */
        new FractionToDoubleDemo().startApp(args);
    }
    
    private void startApp(String[] args) {
        // Some command-line validation:
        if (args.length == 0 || args[0].trim().isEmpty() || !args[0].contains("/")) {
            System.err.println("ERROR! No Command-Line Argument (" 
                             + args[0] + ") OR, Not a Fraction Value! ");
            return;  // Will ultimately exit app.
        }
        // Trim off any leading/trailing whitespaces:
        String input = args[0].trim();  
        System.out.println(input + " is converted to: -> " 
                            + convertFractionToDouble(input));
    }
    
    public static double convertFractionToDouble(String input) {
        /* Get the fractional value from the command-line and 
           remove any leading/trailing whitespaces as well as 
           any that MIGHT be between the numerator, vinculum, 
           and or the denominator:        */
        input = input.trim().replaceAll("(\\s*/\\s*)", "/");
        
        /* Split the numerical (fraction) value on either one 
           (or more) whitespace OR on the fraction vinculum 
           (forward slash). This allows us to split out a whole
           number if one is there:                          */
        String[] numbers = input.split("\\s+|/");
        
        // Validate the supplied fractional value:
        if (numbers.length < 2 || numbers.length > 3) {
            System.err.println("Invalid Fractional Value Supplied! (" + input + ")");
            return Double.NaN;  // Return NaN (Not a Number);
        }
        
        // Are all fractional components integer values?
        for (String s : numbers) {
            if (!s.matches("-?\\d+")) {
                System.err.println("Invalid Fractional Value (" + input + ") Supplied! "
                                 + "All Fraction Components Must Be Integer values!");
                return Double.NaN;  // Return NaN (Not a Number);
            }
        }
        
        /* Convert the Whole Number (if there is one), Numerator, 
           and Denominator to Integer values:            */
        int wn = (numbers.length == 3 ? Integer.parseInt(numbers[0]) : 0);
        int n = (numbers.length == 3 ? Integer.parseInt(numbers[1]) : Integer.parseInt(numbers[0]));
        int d = (numbers.length == 3 ? Integer.parseInt(numbers[2]) : Integer.parseInt(numbers[1]));
        
        /* The Whole Number can be negative but NOT the
           Numerator or the Denominator:    */
        int cnt = 0;
        for (String s : numbers) {
            cnt++;
            if (n <= 0 || d <= 0) {
                System.err.println("Invalid Fractional Value (" + input + ") Supplied! "
                                 + "The Numerator and or Denominator can not be less than 1!");
                return Double.NaN;  // Return NaN (Not a Number);
            }
        }
        // End of Validation:
        
        // Display the Array holding split values: 
        // Remove output after testing:
        System.out.println(java.util.Arrays.toString(numbers));
        
        /* Display Details...Ternary Operator is used here because
           if the array contains a length of 3 then there is also
           a Whole Number that was split out of the supplied value.
           If the array only contains a length of 2 then there is
           no Whole number, there is only a numerator and denominator.  */
        // Remove output after testing:
        System.out.println("Whole Number: " + wn);
        System.out.println("Numerator:    " + n);
        System.out.println("Denominator:  " + d);
        
        // Convert the supplied fractional value to a floating point value:
        double convertion;
        // If the whole number is negative then we subtract the division from the whole number:
        if (wn < 0) {
            convertion = ((double)wn - ((double)n / (double)d));
        }
        // If the whole number is positive then we add the division to the whole number:
        else {
            convertion = ((double)wn + ((double)n / (double)d));
        }
        
        // Remove output after testing:
        System.out.println("Floating Point Value (double type): -> " + convertion);
        
        return convertion;   // Return the convertion;
    }
}

相关问题