Java三进制运算符输出的结果与if else语句不同

vfh0ocws  于 2023-05-12  发布在  Java
关注(0)|答案(3)|浏览(88)

我在写一个程序,它接受一个数字,如果这个数字是整数,它会删除尾随的零。我正在使用三元运算符,但它不像预期的那样工作。但是如果我把它写成if else语句,它就能工作。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double number = scanner.nextDouble();
        System.out.println(((int)number == (double)number) ? (int)number : number); // Always outputs a double

        if ((int)number == (double)number) { // Outputs correct result
            System.out.println((int)number);
        }
        else {
            System.out.println(number);
        }
    }

}

例如,如果我输入5,我得到

5.0
5

如果我输入7.3我得到

7.3
7.3

因此,它似乎适用于if else语句,但不适用于三元运算符。

dwthyt8l

dwthyt8l1#

在if/else语句中,调用PrintStream.println(int)PrintStream.println(double),具体取决于所采用的分支。
使用条件运算符?:你总是调用PrintStream.println(double),因为这是?:表达式的类型。当?:运算符的第二个和第三个操作数具有不同的类型时,编译器根据JLS 15.25的规则选择表达式的总体类型,并在必要时执行适当的转换。
在本例中,整个类型是double,所以就像你在写:

double tmp = ((int) number == (double)number) ? (int)number : number;
System.out.println(tmp);
vshtjzan

vshtjzan2#

这种行为完全没有问题,是由类型解析引起的。
三元运算符本身有一个类型,该类型由可能的结果推断。由于一个结果的类型为(int),另一个结果的类型为(double),因此三元运算符的类型始终为double。
故事的其余部分应该是清楚的。向控制台打印双精度型将始终导致小数点表示。

g0czyy6m

g0czyy6m3#

要扩展有关此问题的信息,请执行以下操作:理解JLS 15.25提供的表的关键是bnp / lub操作,它代表“Binary Number Promotion”/“Least Upper Bound”。
二进制数提升是将较小的数字类型转换为较大的数字类型,以便可以进行整数和浮点运算。这样你就可以在不同类型的数值数据上进行位级操作(比较,等式等)。如果需要,byte(8位)将升级为char(16位),char也将升级为short(16位)。之后,如果需要,短路将被转换为int(32位)以确保操作时的兼容性。如果需要,int(32位)值也会转换为long(64位)。long(64位)和float(32位)将根据需要转换为double(64位)值。
简而言之:使用BNP,较小的数据类型将被转换为较大的数据类型以确保兼容性。
至少上邦德做的几乎相反。如果你有一个short(16位)和一个int(32位),但int不存储大于16位的值,LUB操作将把它缩小到16位。

相关问题