String转换为short[]的整个过程——以汉字“王”为例

 忙了两天,终于整明白了。
 

一、GBK编码

 

GBK中一个汉字用占用两个字节。从GBK编码表可以查到,“王”字的编码为CDF5,即第一个字节为0xCD,转为二进制则是11001101;第二个字节为0xF5,转为二时制则是11110101

 

二、 转换成byte数组bArray[]

 

显然,byte数组的长度为2,其中bArray[0] 11001101bArray[]11110101

 

三、先了解一下补码

 

首先要知道,Java使用补码来表示二进制数。在补码表示中,最高位为符号位,正数的符号位0,负数为1。补码的规定如下:

 

对正数来说,最高位为0,其余各位代表数值本身(以二进制表示),+51的补码为00110011。对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。

 

以负数-51为例:

 

1.    先将-51的绝对值51转换成二进制,即为00110011

 

2.    然后求该二进制的反码,即为11001100

 

3.    最后将反码加1,即为:11001101

 

已知负数的补码求值的步骤,还是以11001101为例(首位为1,所以结果必定是负数)
 

1.    然后求该二进制的反码,即为11001101的反码,得到00110010

 

2.    最后将反码加1,即为:00110011,得出51

 

3.    加上负号,结果为-51

 

四、byte转换成int的过程,为什么要加256? 

 

第一个字节0xCD,即11001101。了解了前面补码的知识后,在只有一个字节(8位)长度时,它的值为-51;但是,同样是11001101,如果4个字节长,即表示为00000000 00000000 00000000 11001101,它代表的是205

 

但是,在转换成intjava中的int4个字节,32位)时,此时Java是用什么来表示-51呢?根据前面说的补码,可以得出:

(1) 51转为二进制,即00000000 00000000 00000000 00110011

(2) 反码,即11111111 11111111 11111111 11001100

(3)1,即11111111 11111111 11111111 11001101

 

11111111 11111111 11111111 11001101加上256(即00000000 00000000 00000001 00000000),就变成了00000000 00000000 0000000011001101,这样就得到了205

 

五、得到int类型的结果

bArray[0]*256+ bArray[1]的结果,即205*256+245=52725,即00000000 00000000 11001101 11110101

 

六、int结果强制转换成short的过程

 

我们知道,Javashort是两个字节长,表示的范围只有-3276832767。从00000000 00000000 11001101 11110101中截取最后16位(两个字节),得到11001101 11110101,根据前面说的根据补码求值的方法:

11001101 11110101的补码是00110010 00001010;加1之后00110010 00001011,即12811;加上负号,得到-12811

 

 

七、附源代码:

 

 

package Test;


public class TestChar {
	
	public static short[] strToShortArray(java.lang.String str)
	{					
		char[] c = str.toCharArray();		
		short[] s = new short[c.length];
		for (int i=0; i<c.length; i++) 
		{
			s[i] = CharToShort( c[i] );
		}					

		return s;
	}		
    public static short CharToShort(char c)
    {
        char[] t = new char[1];
        t[0] = c;
        String strTemp = new String(t);        
        byte[] cc = strTemp.getBytes();
        System.out.println(cc[0]);
        System.out.println(cc[1]);
        
        if (cc.length==1)
        {
            return (short)(cc[0] >= 0 ? cc[0] : cc[0] + 256);
        }
        else
        {
            int v1 = cc[0] >= 0 ? ((int)(cc[0])) : cc[0] + 256;
            int v2 = cc[1] >= 0 ? ((int)(cc[1])) : cc[1] + 256;            
            return (short)(v1 * 256 + v2);
        }
    }	
	public static void main(String[] args)
	{
		String str="王";
		short[] ret=strToShortArray(str);
		for(int i=0;i<ret.length;i++)
		{
			System.out.println(ret[i]);
		}
		return;
	}
}



 

 

输出:

-51

-11

-12811

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值