如果在shift操作符中使用cast操作符呢

qxgroojn  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(521)

jls说
移位表达式的类型是左操作数的提升类型。
如果左侧操作数的提升类型为int,则仅将右侧操作数的五个最低阶位用作移位距离。这就好像右操作数接受了位逻辑“与”运算符&(§15.22.1),掩码值为0x1f(0b11111)。因此,实际使用的移动距离始终在0到31之间(包括0到31)。
如果左侧操作数的提升类型为long,则仅将右侧操作数的六个最低阶位用作移位距离。这就好像右操作数接受了位逻辑“与”运算符&(§15.22.1),掩码值为0x3f(0b111111)。因此,实际使用的移动距离始终在0到63之间(包括0到63)。
如果我使用cast操作符显式生成一个字节和一个短操作数 (byte)100<<100 以及 (short)100<<100 ,右操作数的可用位是多少?
编辑:如果操作数已使用强制转换运算符转换为不同(较小)的类型,则该操作数是否进行数字提升(一元/二进制)?如果是这样的话,您如何解释表达式中包含字节变量 b1 = (byte)(b2 + b3) 因为在强制转换之后,字节结果可能会按照数字提升转换为int?

3qpi33ja

3qpi33ja1#

java8jls还表示§5.6.1:
5.6.1. 一元数字提升
某些运算符对单个操作数应用一元数字提升,该操作数必须生成数字类型的值:
...
否则,如果操作数是编译时类型 byte , short ,或 char ,则升级为类型为的值 int 通过扩大原语转换(§5.1.2).
...
因此,如果我们采用以下表达式:

int i = ...
short s = (short) i << 2;

将导致编译器错误:

Main.java:4: error: incompatible types: possible lossy conversion from int to short
short s = (short) i << 2;

ideone演示
这是因为强制转换绑定到shift的第一个参数,而不是整个表达式。下面是带显式括号的整个表达式:

short s = ((byte) i) << 2;

鉴于

int i = ...;
int j = (short) i << 2;

将成功编译。
ideone演示
所以有效的位子可以用来做任何事 < int 与…相同 int ( 5 比特)因为它们被提升到 int 自动地。
如果将整个表达式的结果转换为,例如。 short ( short s = (short) (i << 2) ,则编译器中不会发生自动操作。但是波希米亚的答案给出了一个逻辑上的界限,即右手操作符的哪些位将有效地影响演员表演后的价值。
在较新的jls版本中,该部分已重新编写。例如,在Java14JLS中,§5.6我们发现(本节缩短为breviety,我建议阅读整段内容以获得完整的上下文):
5.6. 数字上下文
数值上下文适用于算术运算符的操作数、数组创建和访问表达式、条件表达式以及开关表达式的结果表达式。
如果表达式是以下表达式之一,则该表达式将出现在数值算术上下文中:
...
移位运算符的操作数 << , >> ,或 >>> (§15.19). 这些移位运算符的操作数单独处理,而不是作为一个组处理。一 long 移位距离(右操作数)不会将要移位的值(左操作数)提升到 long .
...
数值提升确定数值上下文中所有表达式的提升类型。选择提升类型,以便每个表达式都可以转换为提升类型,并且在算术运算的情况下,为提升类型的值定义运算。数值上下文中表达式的顺序对于数值提升并不重要。规则如下:
...
下一步,扩展基本体转换(§5.1.2)和缩小原语转换(§5.1.3)适用于某些表达式,根据以下规则:
...
否则,所有表达式都不是类型 double , float ,或 long . 在这种情况下,上下文的类型决定了如何选择提升的类型。
在数字算术上下文或数字数组上下文中,升级的类型为 int ,并且任何不属于int类型的表达式都将转换为 int .
在数字选择上下文中,以下规则适用:
...
否则,升级类型为 int ,以及所有不属于类型的表达式 int 将基本体转换为 int .
...

uujelgoq

uujelgoq2#

最大可用移位距离的位数由log2n给出,其中n是用于表示左手类型的值的位数。 byte 有8位。log28是3。所以只使用最右边的3位,给出0-7范围内的移位值。 short 有16位。log216是4。所以只使用最右边的4位,给出0-15范围内的移位值。

相关问题