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

问题描述 投票:1回答:1

但是我正在为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));

我相信最后要做的操作将是结果类型,但是,似乎与上面的示例不同。 (我没有列出任何带有双精度的操作,但是,似乎双精度优先于float。)

[我的另一种想法是,由于它必须执行浮点算术运算,因此会将其转换为最大(32/64)位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了它的事实< [was一个浮点数/双精度数,例如,以下表达式的计算结果为long。

int var1 = (l * i * (int) d * s * b);
但是这种想法的确不足,如果同一表达式中有一个long / float,如果long的值太大而无法容纳float,则您很有可能会丢失信息。
java arithmetic-expressions
1个回答
0
投票
您可以找到in the language spec的两个最相关的细节是:

  • 乘法(以及加法,减法,除法等)是

    left-associative。因此:

    l * i * f * s * b
    评估为

    (((l * i) * f) * s) * b

  • 乘法(以及加法,减法,除法等)的操作数经过binary numeric promotion。松散地,这意味着操作数被扩展为彼此兼容。

    更准确地说:

      如果一个操作数是双精度数,则另一个扩展为双精度数
  • 否则,如果一个操作数是浮点数,则另一个被扩展为浮点数
  • 否则,如果一个操作数为long,则另一个操作数扩展为long
  • 否则,两个操作数都将扩展为int
  • 最后一点告诉你,即使像short和short之类的类型相乘,操作数仍会扩展为int
  • 有这两点:

      l * i很长
    • (l * i) * f是浮点数
    • ((l * i) * f) * s是浮点数
    • [(((l * i) * f) * s) * b是浮点数。
  • 因此,您是从float转换为int。
  • © www.soinside.com 2019 - 2024. All rights reserved.