从byte(字节)的bit(位)层面去理解编码(玩爆底层篇)

举报
YuShiwen 发表于 2022/03/31 00:15:34 2022/03/31
【摘要】 话不多说,直接上干货 干货结论: java不论是负数还是正数在定义、存储、计算的过程中,都是用其补码第二个结论需要自己去体会,详情看下面的2.从byte(字节)的bit(位)层面去理解编码 论证说明...

话不多说,直接上干货

干货结论:

  • java不论是负数还是正数在定义、存储、计算的过程中,都是用其补码
  • 第二个结论需要自己去体会,详情看下面的2.从byte(字节)的bit(位)层面去理解编码

论证说明:

1.Byte类型用二进制八进制十六进制定义数值类型数据举例

用byte存一个负数,比如负27,我们一般情况下用十进制可以这样表示:

byte b1 = -27;

  
 
  • 1

那么用二进制如何去声明负27这个数呢?用气原码,反码,还是补码去声明呢?
我们都知道负27这个数,其:
原码:1001 1011
反码:1110 0100
补码:1110 0101
这里我先直接告诉大家,定义-27这个数的时候用的是补码,存储到内存的时候也是用的补码,参与运算的时候到cpu的通用寄存器中的也是补码。
用二进制(0b)存储-27声明如下:

byte b2 = (byte) 0b11100101;

  
 
  • 1

用八进制(0)存储-27声明如下:

byte b3 = (byte) 0345;

  
 
  • 1

ps:
-27的补码二进制1110 0101转八进制:从后往前每三位二进制的数为一组,高位不足补零,划分为:011 100 101,八进制为:345(八进制)

用十六进制(0x)存储-27声明如下:

byte b4 = (byte) 0xe5;

  
 
  • 1

ps:
-27的补码二进制1110 0101转十六进制:从后往前每四位二进制的数为一组,高位不足补零,划分为:1110 0101,十六进制为:e5(十六进制)

2.从byte(字节)的bit(位)层面去理解编码

2.1Unicode编码与UTF-8编码的关系

  1. Unicode编码:Unicode(统一码、万国码)它是一种理论层面的东西。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
  2. UTF-8编码:是Unicode编码的具体实现,它的UTF-8以字节为单位对Unicode进行编码。
    以下是UTF-8的形式:
  • 0xxxxxx
    说明:它是可变长编码,出现频率较多的字符,如ASCII中的字符,通常是一个字节,这样节省存储空间
  • 110xxxxx 10xxx
  • 1110xxxx 10xxxxxx 10xxxxxx
    说明:汉字通常是3个字节
  • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

ps: xx…x解读:其中一个x对应到Unicode编码中的一bit(位)

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicode的最大码位0x10FFFF也只有21位。

2.2用汉字举例,Unicode编码对应到UTF-8编码

我们可以去查这个字,它的Unicode编码为:55bb(十六进制)
把它转换成二进制为: 0101 0101 1011 1011
的Unicode编码为2个字节占16位,对应到UTF-8的时候,我们需要用到上面2.1中提到的1110xxxx 10xxxxxx 10xxxxxx这种形式,把0101 0101 1011 1011按位填入到xxx中,即把1110xxxx 10xxxxxx 10xxxxxx中的x用0101 0101 1011 1011替换掉。
替换后的结果为:11100101 10010110 10111011
这就是其UTF-8编码,用十六进制表示为:e596bb(十六进制)

java代码举例:用byte数组定义汉字:

public class StringDemo {
    public static void main(String[] args) {
        //二进制形式
        byte[] bytes = {(byte) 0b11100101,(byte) 0b10010110,(byte) 0b10111011};
        //也可以写成十六进制形式
        //byte[] bytes = {(byte)0xe5,(byte)0x96,(byte)0xbb};
        System.out.println(Arrays.toString(bytes));
        System.out.println(binary(bytes,16));

        try {
            String s = new String(bytes, 0, bytes.length, "UTF-8");
            System.out.println(s);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    public static String binary(byte[] bytes,int radix){
        return new BigInteger(1,bytes).toString(radix);
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

测试输出结果:
在这里插入图片描述

文章来源: blog.csdn.net,作者:Mr.Yushiwen,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/MrYushiwen/article/details/119798001

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。