这代码怎么就打印出"hello world"了呢?_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 这代码怎么就打印出"hello world"了呢?

这代码怎么就打印出"hello world"了呢?

 2014/6/8 6:25:02  MouseLearnJava  程序员俱乐部  我要评论(0)
  • 摘要:for(longl=4946144450195624L;l>0;l>>=5)System.out.print((char)(((l&31|64)%95)+32));这段代码有点诡异,输出的结果是helloworld。4946144450195624是64位长整形,它的二进制表达方式为10001100100100111110111111110111101100011000010101000程序用每5个位为一组去解析字符,在for循环中使用l>>5。00100
  • 标签:代码
class="java" name="code">for (long l = 4946144450195624L; l > 0; l >>= 5)
			System.out.print((char) (((l & 31 | 64) % 95) + 32));


这段代码有点诡异,输出的结果是hello world

4946144450195624是64位长整形,它的二进制表达方式为

10001100100100111110111111110111101100011000010101000 程序用每5个位为一组去解析字符,在for循环中使用l >>5


00100|01100|10010|01111|10111|11111|01111|01100|01100|00101|01000
  d  |  l  |  r  |  o  |  w  |     |  o  |  l  |  l  |  e  |  h


小写字母相关的二进制表示方法如下:


ascii   |     ascii     |    ascii     |    algorithm
character | decimal value | binary value | 5-bit codification 
--------------------------------------------------------------
  space   |       32      |   0100000    |      11111
    a     |       97      |   1100001    |      00001
    b     |       98      |   1100010    |      00010
    c     |       99      |   1100011    |      00011
    d     |      100      |   1100100    |      00100
    e     |      101      |   1100101    |      00101
    f     |      102      |   1100110    |      00110
    g     |      103      |   1100111    |      00111
    h     |      104      |   1101000    |      01000
    i     |      105      |   1101001    |      01001
    j     |      106      |   1101010    |      01010
    k     |      107      |   1101011    |      01011
    l     |      108      |   1101100    |      01100
    m     |      109      |   1101101    |      01101
    n     |      110      |   1101110    |      01110
    o     |      111      |   1101111    |      01111
    p     |      112      |   1110000    |      10000
    q     |      113      |   1110001    |      10001
    r     |      114      |   1110010    |      10010
    s     |      115      |   1110011    |      10011
    t     |      116      |   1110100    |      10100
    u     |      117      |   1110101    |      10101
    v     |      118      |   1110110    |      10110
    w     |      119      |   1110111    |      10111
    x     |      120      |   1111000    |      11000
    y     |      121      |   1111001    |      11001
    z     |      122      |   1111010    |      11010


程序将5位值映射到7位ascii字符上去,l & 31 | 64) % 95) + 32


l & 31 用于截取二进制表达式中的最右边5位。


从上表中可以看出,小写字母ascii字符的二进制表达式,第7位和第6位都是1,表示方式为11xxxxx。而space字符只有第六位为1.


因为space字符的特殊性,我们不能简单地使用 (l &31 | 96(96二进制表达式为1100000)表达式获得ascii字符的二进制表示。


为了能够让space和其它小写字母同时处理,采用的方式是将第7位设置为1 - (l &31 | 64) (64的二进制表达式为1000000)。至此,用于表示7位ascii字符的二进制表达式为10xxxxx. 其中Space为1011111,表示成十进制为95。对95求余,使得space归为0,(0000000),程序中的表现为(l & 31 | 64) % 95



最后,我们只要将第6位设置成1,就能得到正确的7位ascii字符表示,程序中的体现为加上32 (二进制100000),((l & 31 | 64) % 95) + 32

 isolates 5 bits --+          +---- takes 'space' (and only 'space') back to 0
                  |          |
                  v          v
               (l & 31 | 64) % 95) + 32
                       ^           ^ 
       turns the       |           |
      7th bit on ------+           +--- turns the 6th bit on


下面再添加一个反向的方法,将由小写字符和空格组成的字符串,转换成64位的Long整形数值。


public static void main(String... args) {
		String v = "hello world";
		int len = v.length();
		long res = 0L;
		for (int i = 0; i < len; i++) {
			long c = (long) v.charAt(i) & 31;
			res |= ((((31 - c) / 31) * 31) | c) << 5 * i;
		}
		System.out.println(res);
	}


转载请注明http://www.wangmengjun.com/showThinkDetail.do?thinkId=1

更多其它信息请访问http://www.wangmengjun.com
发表评论
用户名: 匿名