1

考虑以下代码(其中 byteIndex 是一个 int):

int bitNumber = b-(8*byteIndex);
bitMask = 0x8>>(byte)bitNumber;

这会产生错误

error: possible loss of precision

编译时(必需字节,找到 int)。

编码

int bitNumber = b-(8*byteIndex);
bitMask = 0x8>>2;

编译得很好。

这里有什么问题,如何修复第一个示例以允许按 int 值进行位移?

编辑:在评论之后,这是一个更完整的示例:

48) int byteIndex;
49) byte bitMask;
50) int bitNumber;
    // assign value to byteIndex
67) bitNumber = b-(8*byteIndex);
68) bitMask = 0x8>>bitNumber;

给出的错误是:

...MyClass.java:68: error: possible loss of precision
    bitMask = 0x8>>bitNumber;
             ^
  required: byte
  found:    int
1 error
4

3 回答 3

9

将您的shifting行转换为: -

byte bitMask = (byte)(0x8>>(byte)bitNumber);

您的 RHS 是一个 int,您需要将其类型转换为字节 ..

上面的代码可以正常工作.. 有或casting没有bitNumbertobyte

因此,您还可以拥有:-

byte bitMask = (byte)(0x8>>bitNumber);

但是,这是一个问题 -byte bitMask = 0x8>>3;工作正常.. 为什么会这样?

这是一些示例来解释其工作背后的原因以及以下行为final:-

byte bitMask;
int varInt1 = 3;
final int finalVarInt2 = 3;
final int finalVarInt3 = 4;

bitMask = 0x8>>varInt1;    // 1. Will not work. 
bitMask = 0x8<<3;          // 2. Will work

bitMask = 0x8<<4;          // 3. Will not work
bitMask = 0x8<<finalVarInt2;   // 1. Will work
bitMask = 0x8<<finalVarInt3;   // 2. Will not work

以下是解释上述行为的一些推理: -

  • typecasted只有当编译器确定它能够在 LHS 上的变量中容纳该值时,RHS 上的值才会是隐式的byte。否则,我们必须Explicit type casting告诉编译器,我们知道我们在做什么,只为我们做..

现在让我们一一考虑所有情况(从上面的代码(1-3、1-2):-

  1. varInt1最初包含3。所以RHS的值计算为64。虽然这个值可能会适应LHSbyte的变量,但编译器也知道,可以改变 .. 的值。那么如果在某个阶段将 ..为什么不允许..varInt1varInt1
  2. 现在,在这种情况下,由于我们在Integer Literal这里明确使用了 an,所以编译器确信它会适应byte.. 所以它允许implicit强制转换 ..
  3. 同样,在这种情况下,已知RHS将评估128哪个不能容纳在byte..再次失败..

最后两种情况与常规变量不同...由于它们已声明final,因此无法重新初始化..因此,编译器可以根据分配的值做出决定..

  1. 在这种情况下,编译器会看到,finalVarInt2包含值3。因此,RHS的计算结果为64,可以容纳在LHSbyte上的变量中。现在,由于变量是不能更改的,并且知道这一点,因此可以确定 t*他的值将始终为*.. 所以编译器允许这样做。finalCompiler64

  2. 在最后一种情况下,值为finalVarInt34.. 类似的推理.. 不适合LHS,因为RHS评估为128不适合byte

于 2012-09-28T12:03:29.530 回答
1

在您的第一个示例中,bitnumber 是一个 int(32 位),当您将其转换为一个字节(8 位)时,您将丢失高位 24 位。因此,您正在失去精度。只需关闭演员表(字节)即可。

于 2012-09-28T11:57:21.203 回答
0

事实上这不是答案,正确的答案是 Rohit Jain 写的,但这是我第一次看到 JVM 的这种行为,比较这些代码:

bitNumber标记为最终版本的版本

final int bitNumber = 10;
final byte bitMask = 0x8 >> bitNumber;

bitNumber不是最终版本

int bitNumber = 10;
bitNumber = 10;
final byte bitMask = 0x8 >> bitNumber;

第二个例子有错误,可能是一些优化。如果有人知道原因会很棒;-)

于 2012-09-28T12:23:37.673 回答