我该如何读取可能是整数或双精度浮点数的输入?

6

我正在编写一个程序,需要从键盘输入数据。我需要接收一个数字输入,但是我不确定它是int还是double类型。以下是我处理这个问题的代码:

import java.io.*;
import java.util.*;

//...
Scanner input  = new Scanner(System.in); 
int choice = input.nextInt();

我知道我可以获得一个String并使用parseInt()或者parseDouble(),但是我不知道它将是哪一个。


1
实际上,最好读入一个 String。然后,您需要验证给定的数字是数字。如果它包含一个点或逗号,并且左右两部分都是数字,那么它就是一个 double。否则,如果没有点或逗号但其余部分是数字,则为 int。用于检查是否为双精度浮点数可以使用此 正则表达式:"-?\d+(\.\d+)",对于数字,您可以使用 "[0-9]*"。 - pietv8x
@pietv8x 当然,这个正则表达式模式只能可靠地适用于一些格式类似于英文的浮点数的语言环境。即使在英文环境中,整数数据也可能包含分组分隔符等,这可能会导致错误。 - Hulk
4个回答

5

整数也可以当作双精度浮点数来处理,因此,如果您将一切都看做双精度浮点数,那么您的逻辑就可以得到正确的结果。请参考以下示例:

import java.io.*;
import java.util.*;
Scanner input  = new Scanner(System.in); 
double choice = input.nextDouble();

只有在某些情况下需要将输入转换为整数时,才会变得复杂。然后,使用parseInt()来测试整数就可以了。


虽然我同意你的答案,但我觉得你的第一句话有点误导人。确实,整数值通常可以用double类型表示,但我不会说int就是double。它们不仅具有不同的内存占用(int使用4个字节,而double使用8个字节),而且它们实际存储值的方式也有所不同。这对于OP来说完全无关紧要,你的答案肯定适用于他/她,但我只是想为未来的读者留下这个问题。幸运的是,如果值确实是整数,从double到int的转换是很容易的。 - JNYRanger

3

无论是什么,只需使用double。对于整数值使用double没有明显的损失。

Scanner input = new Scanner(System.in); 
double choice = input.nextDouble();

接下来,如果你需要知道是否得到了一个双倍数,你可以使用Math.floor进行检查:

if (choice == Math.floor(choice)) {
    int choiceInt = (int) choice);
    // treat it as an int
}

不要试图使用catch捕获NumberFormatException,也不要在字符串中搜索句点(这可能并不正确,例如输入为1e-3时,它是一个双精度浮点数(0.001),但没有句点。只需将其解析为double并继续进行即可。

此外,不要忘记nextInt()nextDouble()不会捕获换行符,因此在使用它们后需要使用nextLine()捕获该字符。


谢谢。你给我的第二个代码块中的int语句非常简单易懂,但非常有帮助。 - newplayer12132

0
你可以尝试使用 floor 函数来检查一个数是否为 double 类型。如果你不知道,floor 函数基本上会将任何小数部分截断。因此,你可以将有小数和没有小数的数字进行比较。如果它们相同,则该数字可以被视为整数,否则为 double 类型(假设你不需要担心像 long 这样的大数字)。
String choice = input.nextLine();

if (Double.parseDouble(choice) == Math.floor(Double.parseDouble(choice)) {
    //choice is an int
} else {
    //choice is a double
}

哦,我刚从问题中获取了该方法,并没有意识到它不在String类中。已修复,谢谢。@durron597 - Zarwan
我已经取消了我的反对意见,但是没有必要两次调用“parseDouble”。 - durron597

0
我会获取字符串输入,并将其解析为双精度浮点数或整数。
String str = input.next();
int i = 0;
double d = 0d;
boolean isInt = false, isDouble = false;

try {
    // If the below method call doesn't throw an exception, we know that it's a valid integer
    i = Integer.parseInt(str);
    isInt = true
}catch(NumberFormatException e){
    try {
        // It wasn't in the right format for an integer, so let's try parsing it as a double
        d = Double.parseDouble(str);
        isDouble = true;
    }catch(NumberFormatException e){
        // An error was thrown when parsing it as a double, so it's neither an int or double
        System.out.println(str + " is neither an int or a double");
    }
}

// isInt and isDouble now store whether or not the input was an int or a double
// Both will be false if it wasn't a valid int or double

这样,您可以确保通过解析双精度数而不是整数不会失去整数精度(双精度数具有不同范围的可能值),并且您可以处理既未输入有效整数也未输入双精度数的情况。
如果在try块内的代码引发异常,则执行catch块中的代码。在我们的案例中,如果parseInt()方法引发异常,则我们执行catch块中的代码,在其中包含第二个try块。如果parseDouble()方法引发异常,则我们将执行第二个catch块中的代码,该代码打印错误消息。

我不是那个点踩的人,但是:在处理区域设置和数字格式问题方面,Integer.parseIntScanner.nextInt(或其双精度版本)要少得多。(即:如果遇到任何非数字ASCII字符,它什么也不做,只会抛出异常) - Hulk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接