计算机储存数字和字符的方法你了解多少?( 二 )


【计算机储存数字和字符的方法你了解多少?】至于计算机为什么用补码来储存数字 , 而不是原码 , 原因是:
拿单字节整数来说 , 无符号型 , 其表示范围是[0,255] , 总共表示了256个数据 。有符号型 , 其表示范围是[-128,127] 。
先看无符号 , 原码和补码都一样 , 0表示为0000 0000 , 255表示为1111 1111 , 刚好满足了要求 , 可以表示256个数据 。
再看有符号的 , 若是用原码表示 , 0表示为0000 000 。因为咱们有符号 , 所以应该也有个负0(虽然它还是0)1000 0000 。这样的话那就有2个0 , 也就是只能表示255个数据 , 不能够满足我们的要求 。而用补码则很好的解决了这个问题 。
字符
在计算机中 , 对非数值的字符进行处理时 , 要对字符进行数字化 , 即用二进制编码来表示字符 。其中西文字符最常用到的编码方案有ASCII编码和EBCDIC编码 。对于汉字 , 我国也制定的相应的编码方案 , 比如 GBK , GB2312等 。
比如字符a的ASCII码十进制值为97 , 在计算机中用二进制表示就是 01100001 。下面同样用Java来演示计算机是如何储存字符的 。

  1. 采用UTF-8和GBK两种编码储存汉字

计算机储存数字和字符的方法你了解多少?

文章插图
 

计算机储存数字和字符的方法你了解多少?

文章插图
 
我们调试看看 , 发现GBK编码采用2个字节储存 , 储存的数据分别是10进制的-42和-48对应的二进制分别是11010110和11010000(补码) , 即汉字中对应的二进制为1101011011010000 , 即16进制的D6D0 , 查看GBK对照表 , 发现16进制编码D6D0对应的汉字确实是中
计算机储存数字和字符的方法你了解多少?

文章插图
 
而UTF-8编码采用3个字节储存 , 同理将对应的二进制111001001011100010101101转成16进制 , 为E4B8AD , 通过UTF-8编码查询 , 发现汉字中对应的16进制编码确实是E4B8AD
 
计算机储存数字和字符的方法你了解多少?

文章插图
 
  1. 储存字符

计算机储存数字和字符的方法你了解多少?

文章插图
 

计算机储存数字和字符的方法你了解多少?

文章插图
 
调试看看 , 字符串EF有E和F两个字符 , 它们对应的十进制ASCII码分别是69和70
计算机储存数字和字符的方法你了解多少?

文章插图
 
我们发现Java的getBytes()方法是将字符串的每一个字符都储存到一个字节的 , 如果我们想把EF储存在一个字节里面 , 即EF是一个整体的 , 一个字节 , 不能拆分 , 那我们可以把EF放在一个字节里面(byte)(0xEF) , 声明它是一个字节 , 不是字符 , 不用再将它转成字符对应的编码 。
下面说说我在进行MD5消息摘要算法时候遇到的坑 , 我要对QQ号对应的Hex进行MD5算法散列 , 这里我举例QQ号的10进制为12345678 , 对应的16进制为00BC614E(因为QQ号固定长度4个字节 , 所以前面补了2个0) , 一开始我是以下面的方式进行MD5算法的
计算机储存数字和字符的方法你了解多少?

文章插图
 

计算机储存数字和字符的方法你了解多少?

文章插图
 
调试可以看到上面的代码其实是将字符串00BC614E转成了8个字节 , 然后再对这8个字节进行散列 , 这也是基于字符串进行的MD5散列 , 和通过网上一些网站散列得到的值是一样的
计算机储存数字和字符的方法你了解多少?

文章插图
 
但是这个哈希值和预想的结果不一致 , 后来才知道预想的结果是基于字节进行的MD5散列 , 也就是00BC614E应该分成4个字节(00、BC、61、4E)而不是8个字节(0、0、B、C、6、1、4、E) , 然后通过修改代码
计算机储存数字和字符的方法你了解多少?

文章插图
 

计算机储存数字和字符的方法你了解多少?


推荐阅读