为什么在 Java 中使用 scanner 类和分隔符来获得双精度时会得到错误的数学结果?

Why do I get wrong mathematical results when using scanner class and delimiters for getting a double in Java?

提问人:Msitake 提问时间:11/16/2020 更新时间:11/16/2020 访问量:55

问:

我正在编写一个程序,我必须获取用户输入,保存为双精度。用户必须能够同时使用“和”.“作为分隔符 - 随心所欲。我尝试使用仅部分工作的 useDelimiter - 它确实接受两个值(例如 4.5 和 4,5),但是当我后来在数学方程式中使用输入的值时,我得到了错误的结果 - 它似乎将用户输入四舍五入到最接近的整数,并且无论我输入 4 还是 4.5 还是 4,5 还是 4.8 等,它都会产生效果, 我得到相同的结果,这实际上只适用于 4。 有没有人碰巧知道为什么它不起作用?

  double protectiveResistor=0;                //must be a double, required by my teacher
  double voltage= 5;    
  System.out.println("Please provide the resistance.");
        Scanner sc= new Scanner(System.in);
        sc.useDelimiter("(\\p{javaWhitespace}|\\.|,)");

        try
        {
            protectiveResistor=sc.nextDouble();
        }
        catch(InputMismatchException exception)
        {
            System.out.println("Wrong input!");
            System.exit(1);
        }

        if (protectiveResistor<0){
            System.err.println("Wrong input!");
            System.exit(1);
        }
        
        double current = (double)voltage/protectiveResistor;
        double power = (double)current*current*protectiveResistor;

谢谢!

java try-catch java.util.scanner 用户输入 csv

评论


答:

1赞 Dawood ibn Kareem 11/16/2020 #1

该方法是告诉什么字符将数字彼此分开。它不是为了指定哪个字符将是小数点。因此,对于您的代码,如果用户输入 或 ,则会将其视为两个单独的输入,并且 .useDelimiterScanner4.54,5Scanner45

不幸的是,它没有允许您指定两个不同字符作为小数分隔符的功能。你唯一能做的就是分别扫描这两个数字,然后将它们连接成一个十进制数。您需要将它们扫描为值,这样您就不会在小数点后丢失任何零。ScannerString

1赞 TobiWestside 11/16/2020 #2

useDelimiter() 的作用是拆分指定分隔符上的输入。 例如,如果您输入了 ,则以下代码将打印“4”。4,5

Scanner sc= new Scanner(System.in);
sc.useDelimiter(",");
System.out.println(sc.next())

如果您还想打印第二部分,则在“,”之后,您需要添加另一行以获取下一个值,在此示例中将打印 "4 5":

Scanner sc= new Scanner(System.in);
sc.useDelimiter(",");
System.out.println(sc.next())
System.out.println(sc.next())

在代码中,你可以这样做:

Scanner sc= new Scanner(System.in);
sc.useDelimiter("(\\p{javaWhitespace}|\\.|,)");

try
{
    String firstPart = "0";
    String secondPart = "0";
    if (sc.hasNext()) {
        firstPart = sc.next();
    }
    if (sc.hasNext()) {
        secondPart = sc.next();
    }
    protectiveResistor = Double.parseDouble(firstPart + "." + secondPart)
}
// Rest of your code here

此代码的作用是将输入拆分为空格 '.' 和 ','。对于浮点值,您期望在小数点之前有一个部分,在小数点之后有一个部分。因此,您希望扫描仪将输入分成两部分。这两个部分分配给两个变量,并且 .在最后一步中,按照 Java 的预期,将这两个部分与 '.' 作为小数点放在一起,并解析回 Double 类型的变量。firstPartsecondPart

评论

0赞 TobiWestside 11/16/2020
感谢您的评论,我已经更新了我的答案以使用 next() 而不是 nextDouble(),这应该可以解决这个问题
1赞 Dawood ibn Kareem 11/16/2020
现在看起来好多了。