java - java如何定义算术表达式的结果

标签 java arithmetic-expressions

我正在为 Java 编写解析器,但是,当涉及到基本类型的操作时,我有点迷茫。

例如我有这些表达式:

int i;
long l;
float f;
short s;
byte b;
//this is being cast from a float to an int? should this be a cast from byte?
int var1 = (int) (l * i * f * s * b);
//this is being cast from a float to an int? should this be a cast from long?
int var2 = (int) (l * (i * f * s * b));
//again casting from float to int? should this be a cast from short?
int var3 = (int) ((f) * (l) * (s));
//this seems to be a float but i expected this to be a long
int var4 = (int) ((f) * (l));

我认为最后要完成的操作将是结果类型,然而,这似乎不是上述示例中的情况。 (我没有列出任何与 double 相关的操作,但是,似乎 double 像 float 一样优先。)

我的另一个想法是,因为它必须进行浮点运算,所以它正在将其转换为最大的 (32/64) 位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了它的事实一个 float / double ,例如以下表达式的计算结果为长整型。

int var1 = (l * i * (int) d * s * b);

但是,这种想法确实不尽如人意,好像在同一个表达式中有一个 long/float,如果 long 的值太大而无法放入 float,您很可能会丢失信息。

最佳答案

两个最相关的细节,你可以找到in the language spec , 是:

  • 乘法(以及加法、减法、除法等)是左结合。所以:

    l * i * f * s * b
    

    被评估为

    (((l * i) * f) * s) * b
    
  • 乘法(以及加法、减法、除法等)的操作数经过 binary numeric promotion .粗略地说,这意味着操作数被扩大以相互兼容。

    更准确地说:

    • 如果一个操作数是 double ,则另一个加宽为 double
    • 否则,如果一个操作数是 float ,则另一个被加宽为 float
    • 否则,如果一个操作数是long,则另一个被加宽为long
    • 否则,两个操作数都被扩展为 int

    最后一点告诉你,即使相乘类似的类型,比如 short 和 short,操作数仍然扩大到 int

有了这两点:

  • l * i 是长
  • (l * i) * f 是一个 float
  • ((l * i) * f) * s 是一个 float
  • (((l * i) * f) * s) * b 是一个 float 。

因此,您正在从 float 转换为 int。

关于java - java如何定义算术表达式的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58365736/

相关文章:

java - LWJGL 使用 PBO 读取像素失败

java - 如何使用 Spring Boot 将数据从一个 html 表单传递到多个表

java - 二维数组重写

c - 添加字符串和 ssize_t?

bash - bash 中 $[a-b] 和 $((a-b)) 之间的区别

python - 使用 python 数组列进行算术运算

java - 如何将 jUnit 5 与 Gradle 结合使用

java - jsoup 解析框架集和 id 属性的问题

java - 算术表达式未在函数调用中解析

c++ - 为什么代码片段会抛出浮点异常?