数据的二进制表示与数据类型转换

date: 2019-04-30

数据的二进制表示

以下先以 java 中的 byte 类型为模板将(长度短,代码好写。。。)

    byte b1 = (byte) 0b00000000;//0b 表示后面的数据用二进制表示,0 为八进制,0x 为十六进制,十进制不带前缀
    byte b2 = (byte) 0b10000000;
    byte b3 = (byte) 0b11111111;
    System.out.println(b1);
    System.out.println(b2);
    System.out.println(b3);
    //以上的输出结果为 0、-128、-1

为何二进制与数据是这么对应的?个人理解是方便计算机进行运算。试想以下情况:

  • 有一个数 x 的值为 -128,我们使 x 加一变为 -127,如果 -128 的二进制表示为 0b11111111,那么 -127 应当为 0b11111110,虽然值 +1,但是二进制表示却是 -1,底层不符合逻辑。所以逻辑一点,表面上既然 +1,那底层最好也 +1,所以 -1280b10000000 来表示更合理,-127 则相应的为 0b10000001,底层的确比 -1281

以这种方法表示,0b11111111 则表示 -1,而 -1 加一之后为 0,二进制加一为 0b100000000 ( 8 个 0 ),因为 byte 长度为一个字节,即只有 8 bits,溢出的 1 被舍去,剩下为 0b00000000,正好为 0,符合 -1 + 1 = 0

数据类型转换

上面的东西看完之后,我们进入正题。

之前我正在用 java 来实现通信,期间需要将各种数据与 byte 类型进行转换,而在将 byte 型转成 int 型数据时发现了一件事情。以如下代码为例:

    byte b = (byte) 0xff;//即255
    System.out.println(b);
    System.out.println((int) b);
    System.out.println(b & 0xff);
    System.out.println((int) (b & 0xff));
    System.out.println(b | 0x00);
    System.out.println((int) (b | 0x00));

三行输出分别为 -1、-1、255、255、-1、-1

真是一件很令人头疼的事

我们先得出以下结论:

  • 是否进行强制类型转换对结果没有影响
  • byte 型数据与 0 进行或 ( | ) 运算不会使输出结果发生改变(即以 byte 类型输出,值域为 -128~127
  • byte 型数据与 0xff(相对于 8 bits 的数据来说即各位全是 1 )进行与 ( &) 运算,会以比 byte 值域更大的域来输出,输出的数据明显超过了 byte 的值域

现在我们来看看下面这种情况:

    byte b = (byte) 0xff;
    int num = (int) b;
    System.out.println(num );
    System.out.println(num  & 0xff);
    System.out.println(num  & 0xffff);
    System.out.println(num  & 0xffffffff);
    System.out.println(num  | 0x00);

我们提前将 byte 类型转换成了 int 类型,输出结果如下:-1、255、65535、-1、-1

显然,num 的二进制表示为 0b111111111111111111111111 ( 32 个 1 )

我们又得出以下结论:

  • byte 型转换成 int 型时(可以拓展为短数据类型转换成长数据类型),会保持值不变(负数高位补 1,正数高位补 0
  • 与上面相反,将 int 型转换成 byte 型时(长变短),如果发生溢值,则会舍弃高位,保留低位

以上就是我进行的全部测试

但是这里还有一个问题没有解决,希望有大神能给我一些帮助:

  • 为什么 b&0xffb\|0x00 的值不一样,理论上两者都不会使值发生变化

至此,我想讲的就讲完了,谢谢大家的阅读。

个人博客:https://wilfredshen.cn/

posted @ 2020-05-08 23:35  三尺青锋丶  阅读(483)  评论(0)    收藏  举报