android - 从 Byte 扩展到 Int(Marshmallow 错误)

标签 android android-6.0-marshmallow

提前对这个冗长的问题表示抱歉,但一切都应该直截了当并清楚发生了什么,感谢您的关注。请注意,这实际上不是代码,只是用于理解应用程序实现的伪代码。

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/

相关文章:

android - 如何从 OPEN_DOCUMENT Intent 获取文件系统路径?

android - 如何以编程方式关闭棉花糖设备中特定应用程序的打瞌睡模式

java - OAuth:缺少参数response_type

android - 使用 Android Studio Google Maps Activity 不显示 map

java - Java中巨大的Json字符串转义的最佳方法是什么

Android:ContextCompat.getColor(上下文,R.color.my_color),无法解析 "getColor"

android - 切换到 RINGER_MODE_VIBRATE 时防止手机振动

java - 隐藏信息窗口 android map api v2

android - 是否可以通过网络浏览器通过 url 方案启动 android wifi 设置?

android - 不幸的是,Package Installer 在 Marshmallow 中请求权限时已停止