提前对这个冗长的问题表示抱歉,但一切都应该直截了当并清楚发生了什么,感谢您的关注。请注意,这实际上不是代码,只是用于理解应用程序实现的伪代码。
Issue
字节没有扩大到真正的数值。注意:level = -1
表示游戏还没有开始。 level == 24
代表游戏结束。
1 级
private byte level = -1;
private byte stage = 0;
@NonNull private final Stages[][] stages = new Stages[25][13];
public byte getLevel () {
return level;
}
public void nextLevel () {
// expect: 0
level++;
// stages[ 128][ 0] (ArrayIndexOutOfBounds)
stages[level][stage] = new Stage();
}
2 类扩展了 1 类
@NonNull private final byte[][] values = new byte[25][4];
public byte getScore (final byte level, final byte player) {
// values[ 255][ 2] (ArrayIndexOutOfBounds)
return values[level][player];
}
// expecting: -1 >= 0 (false)
// runtime: 255 >= 0 (true)
if (Class1.getLevel() >= 0)
getScore(Class1.getLevel(), 2);
Binary
8 位(字节)
-1 == 1111 1111
-128 == 1000 0000
127 == 0111 1111
32 位(整数)
-1 == 1111 1111 1111 1111 1111 1111 1111 1111
127 == 0000 0000 0000 0000 0000 0000 0111 1111
128 == 0000 0000 0000 0000 0000 0000 1000 0000
255 == 0000 0000 0000 0000 0000 0000 1111 1111
What Worked
使用包装类
public Byte level = -1;
Question
我理解问题是数字的二进制表示在从 byte 扩展到 int 时被直接使用。我的号码实际上是从 8 位 1111 1111
到 32 位 0000 0000 0000 0000 0000 0000 1111 1111
。我的问题是为什么 Java(或者为什么它不在这种情况/环境中)在扩大时不将数字转换为真实数值,而不是仅仅将零填充到原始二进制表示形式。
这似乎只发生在负数上,我假设是因为正数在加宽前后具有相同的位表示。
为什么我的号码没有从 8 位 1111 1111
变为 32 位 1111 1111 1111 1111 1111 1111 1111 1111
?为什么后缀增量创建值 128..?除了我目前遇到的问题之外,还有更好的解决方案吗?
我不想在不知道下划线问题的情况下就使用该解决方案,因为该问题可能会悄悄地(无错误地运行)破坏我的应用程序算法;因此,如果有人可以向我解释这个问题,我将不胜感激。
谢谢,杰
Current Working Environment
JDK 1.8.076
操作系统 X El Capitan
Android Studio 2.2 预览版 2
buildToolsVersion '23.0.3'
类路径 'com.android.tools.build:gradle:2.2.0-alpha2'
模拟器 Nexus 6P API 23 x86
Conclusion
我能够将问题缩小到仅 Android 23 (Marshmallow) 设备。我已经向谷歌公司报告了这个错误。感谢大家的帮助,我只是向 Android 23 (Marshmallow) 用户发出警告,因为该错误不会出现在 Android N、Android 22 及更低版本中。
最佳答案
为什么不将有符号字节转换为无符号字节?
public static int signedByteToInt(byte b) {
return b & 0xFF;
}
为您确保此处是带符号字节的表示示例:
-3 - 11111101
-2 - 11111110
-1 - 11111111
0 - 00000000
1 - 00000001
2 - 00000010
3 - 00000011
当你使用 byte 作为 int 时,java 无论如何都会将这个字节表示为有符号字节,所以从 11111111 (-1) 你会得到 11111111 11111111 11111111 11111111 (-1) 我在这里看不到任何问题。
请记住:
from -1 to -128 is from 11111111 to 10000000
and from 0 to 127 is from 00000000 to 01111111
并在将其用作 int 时进行适当的转换。
所以低于零的表示就像向后反中间
顺便说一下,这不仅在 java 中)
这里:
if (Class1.getLevel() >= 0)
你比较字节和整数,试着做:
if (Class1.getLevel() >= (byte)0)
并感到快乐:)
关于android - 从 Byte 扩展到 Int(Marshmallow 错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37572878/