和硬件调试那些事

976 阅读3分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

和硬件调试那些事

由于JAVA是数据类型有符号的,也就是有负数,以至于和硬件调试经常产生奇奇怪怪的问题,我把遇到的问题和解决方法列出来,也给大家提个醒。

JAVA 基本类型

java中的基本类型有八种,这八种是如何对应byte的呢,我们和硬件打交道可都是byte啊。

byte(字节) = 8位 = 1字节 short(短整数)= 16位 = 2字节 int(整数)= 32位 = 4字节 long(长整数)= 64位 = 8字节 float(单精度)= 32位 = 4字节 double(双精度)= 64位 = 8字节 char(字符)= 16位 = 2字节 boolean(布尔值)8位 = 1字节

由于java是带符号位存储,有负数,所以java中的范围和硬件那边就不一样了。

比如我们协议中定义的一个byte是0-255,但在java中byte的范围是[-128, 127]

那么我们java语言传递一个byte给硬件,硬件获取的范围就是[-128, 127]了吗? 不是的,byte还是那个byte,只是表现形式取值方式变了。

有点绕,举个例子,橘生淮南则为橘生于淮北则为枳。 还绕吗?🥔 有些地方管它叫土豆,有些地方管它叫洋芋

踩坑

那么我遇到了什么问题呢。

有一个输入框记录值,硬件定义它是两个字节,我们java理所当然的定义成了short类型。为了不超过类型的范围,我还小心翼翼的限制了数据框范围

  • 只能输入正数
  • 范围是0-65535

一切看起来都没有问题。 然后我

String inputStr = "65535";
short value = Short.parseShort(inputStr);

在short范围内都没有问题,但当值超过32767就报错了java.lang.NumberFormatException: Value out of range. Value:"65535" Radix:10

原因是值超出了short的范围,分析一下:

  • 0-32767 之间的数值正常运行
  • 32768-65535 报错
  • 65535的数忽略,超出范围。

那么怎么用范围[-32768,32767]的short去表示之间的32768-65535这些数呢?

String inputStr = "65535";
int valueInt = Integer.parseInt(inputStr);
short value = (short) valueInt;
Log.d(TAG, "value:" + value); // -1

虽然short value在java中输出是负数,但换种方式获取,它就是正常的数值了。

看看下面的这段方法,short转integer(考虑到short可能会超出范围特殊处理下)

    public static Integer shortToInteger(Short s) {
        if (s < 0) {
            return 65535 + 1 + s; // 为什么是65535+1,这是因为中间还有一个0,不然少算了
        } else {
            return new BigDecimal(s).intValue();
        }
    }
String inputStr = "65535";
int valueInt = Integer.parseInt(inputStr);
short value = (short) valueInt;
Log.d(TAG, "value:" + shortToInteger(value)); // 65535

这样就可以正常的输出了。 相应的,假设硬件那边给我们short=-1的值,我们也需要shortToInteger之后再显示。 说白了,也就是有符号位和无符号位之间的转换。