![548d37e91b15d56b6cbfb0dd5e838741.png](https://i-blog.csdnimg.cn/blog_migrate/94fc44fe05514506d41243c44647bb4a.jpeg)
原码,补码,反码
因为原码,补码,反码比较简单,我这里粘贴一个例子进行展示。
![e6c268b5cb8bf00c16ca7484968c3771.png](https://i-blog.csdnimg.cn/blog_migrate/c9394f2596304d0fa6677ad9302e8d0b.jpeg)
Unicode 和 UTF-8 的关系
Uincode 是一个字符集。它规定了我们使用到的字或符号的码点(code point)。码点使用 16 进制保存。
![ea7ff0d57958f414fc79da8aced01a8c.png](https://i-blog.csdnimg.cn/blog_migrate/799f86fc7da5923df765f64abee0115e.jpeg)
Uincode 字符集规定 一 的码点为 4E00。
Uincode 字符集规定 丁 的码点为 4E01。
计算机呢只能识别二进制的 0 和 1。而 UTF-8 指的是编码规则,规定码点怎么保存成二进制。
还有别的 Unicode 编码规则,UTF-16 和 UTF-32。
![f2f3218087ee4398aec8fb97fa9b3c36.png](https://i-blog.csdnimg.cn/blog_migrate/c93f43918830cf987c747ae038fa1279.png)
上述表格简单描述了Unicode 按 UTF-8 编码的格式。
- 首先将 16 进制的码点,通过进制转换 为十进制
- 然后使用十进制的数字查找上述表格处于哪个范围中,得出编码规则。
- 然后将码点转换为 2 进制,从低位到高位替换 x 即可得到字二进制的原码
- 将二进制的原码转换为补码存储。
java 内存中的字符串采用的是 unicode 编码,也就是内编码。我们可以从 unicode 转变为 GBK 或 UTF-8 等其它规则。
代码验证猜想
以赵为例子讲解。
赵的码点为:8D75
16 进制的码点转换为 10 进制:36213
36213 处于 2048-65535 ,得出对应的 UTF-8 编码格式为:1110xxxx 10xxxxxx 10xxxxxx
赵的 16 进制码点 8D75 转换为二进制 1000
将二进制填充在 1110xxxx 10xxxxxx 10xxxxxx 中的 x 中,不足的补 0.
11101000 10110101 10110101。
对三个字节分别求补码为:
原码:11101000 10110101 10110101
补码:10011000 11001011 11001011
补码对应 java 中的字节数组为:{-24,-75,-75
![6fc7fdaf7c472e8a80fc873aae362892.png](https://i-blog.csdnimg.cn/blog_migrate/4f6e9868aefda2463547db8ce1c99317.png)
- 再加一个例子:
且的码点:4E14
16 进制的码点转换为 10 进制:19988
19988 处于 2048-65535 ,得出对应的 UTF-8 编码格式为:1110xxxx 10xxxxxx 10xxxxxx
16 进制的码点转换成二进制:100111000010100
原码:11100100 10111000 10010100
补码:10011100 11001000 11101100
补码对应的字节数组为:{-28,-72,-108}
![54ee7f25bf018ec2a41e2efedc506541.png](https://i-blog.csdnimg.cn/blog_migrate/4486e2dc59e84b553f640d31a5fcc3f2.png)
GBK 转码
赵的 GBK 码点为:D5D4 十六进制码点转换为二进制:11010101 11010100 源码:11010101 11010100 补码:10101011 10101100
补码对应的字节数组为:{-43,-44}
![40fdda7042e5775fda81300ec88accd0.png](https://i-blog.csdnimg.cn/blog_migrate/2cb86bddb4009014e48da6340019cb11.png)
JAVA 中乱码问题
java 字符或字符串采用 uincode 作为内编码。
![f90727263354082329ca4eb132683674.png](https://i-blog.csdnimg.cn/blog_migrate/d9de9de3e2d6d60c372adb11764c9206.png)
编码:字符串到字节。
解码:字节到字符串。
当我们读取文件的时候实际读取的是字节。然后根据文件的编码格式,将字节解码成字符串。乱码问题容易出现的地方就是这里。
不要妄想将一个乱码的字符串变成一个非乱码的。这个思路是错误的。应该从乱码之前的字节着手处理。
![d1b48978db2fb543bfcee2865a4de948.png](https://i-blog.csdnimg.cn/blog_migrate/a4686ae7857f28e54719336e3bf8ffdf.png)
上述例子中的 s 已经乱码了,当你操作这个 s 获取字节也是乱码的。
因此思路是操作 gbks 转换解码方式获取字符串。