【问题标题】:"possible loss of precision" is Java going crazy or I'm missing something?“可能的精度损失”是 Java 发疯了还是我遗漏了什么?
【发布时间】:2010-05-09 20:36:49
【问题描述】:

我得到一个“精度损失”错误,但应该没有,AFAIK。

这是一个实例变量:

byte move=0;

这发生在这个类的方法中:

this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF);

move 是一个字节,move 还是一个字节,剩下的都被转换成一个字节。

我收到此错误:

[javac] /Users/looris/Sviluppo/dumdedum/client/src/net/looris/android/toutry/Guy.java:245: possible loss of precision
[javac] found   : int
[javac] required: byte
[javac]             this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF);
[javac]                                         ^

我尝试了很多变体,但仍然遇到同样的错误。

我现在一无所知。

【问题讨论】:

  • 如果move是128怎么办?当您将其移动 4 位时,将导致精度损失。 “byte

标签: java casting precision


【解决方案1】:

实际上所有的逻辑运算符(& | ^)都返回一个int,不管它们的操作数是什么。您还必须转换 x|y 的最终结果。

【讨论】:

  • 哦!谢谢! (也对 leonbloy 和 ZZ)
【解决方案2】:

那是因为 this.move&lt;&lt;4 返回一个 int。

当Java 找到a shift operator 时,它会将unary promotion 应用于每个操作数;在这种情况下,两个操作数都被提升为int,结果也是如此。 其他 Java 运算符的行为类似;请参阅相关且有启发性的讨论,“Varying behavior for possible loss of precision”。

【讨论】:

  • 该链接对我非常有用,但没有关于按位移位的示例。那里的解释是关于复合赋值语句。
【解决方案3】:

按位或操作数受二进制数字提升。这是它在 JLS 中的定义方式,

5.6.2 二进制数字提升

当运算符应用二进制时 数字提升到一对 操作数,每个都必须表示一个 数值类型的值,如下 规则适用,按顺序,使用扩大 转换(§5.1.2)转换 必要的操作数:

  • 如果任一操作数为 double 类型,则另一个将转换为 双倍。
  • 否则,如果任一操作数为浮点类型,则将另一个转换为 漂浮。
  • 否则,如果任一操作数为 long 类型,则另一个为
    转换为长。
  • 否则,两个操作数都将转换为 int 类型。

如您所见,没有字节类型,因此默认情况下所有字节都提升为 int。您必须将其转换回字节以消除警告,

this.move=(byte)((this.move<<4)|(Guy.moven.indexOf("left")&0xF));

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 2021-08-22
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多