这怎么打印“hello world”? [英] How does this print "hello world"?

查看:168
本文介绍了这怎么打印“hello world”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现这个奇怪之处:<​​/ p>

I discovered this oddity:

for (long l = 4946144450195624l; l > 0; l >>= 5)
    System.out.print((char) (((l & 31 | 64) % 95) + 32));

输出:

hello world

这是如何工作的?

推荐答案

数字 4946144450195624 符合64位,其二进制表示为:

The number 4946144450195624 fits 64 bits, its binary representation is:

 10001100100100111110111111110111101100011000010101000

程序从右到左解码每个5位组的字符

The program decodes a character for every 5-bits group, from right to left

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



5位编码



5位,可以表示2⁵= 32个字符。英文字母包含26个字母,除了字母外,还留有32 - 26 = 6个符号
的空间。通过这种编纂方案,您可以拥有所有26个(一个案例)英文字母和6个符号(其中包含空格)。

5-bit codification

For 5 bits, it is posible to represent 2⁵ = 32 characters. English alphabet contains 26 letters, this leaves room for 32 - 26 = 6 symbols apart from letters. With this codification scheme you can have all 26 (one case) english letters and 6 symbols (being space among them).

for-loop中的>> = 5 从一个组跳到另一个组,然后5位组被隔离并使用掩码 31 10 = 11111 2 在句子 l& 31

The >>= 5 in the for-loop jumps from group to group, then the 5-bits group gets isolated ANDing the number with the mask 31₁₀ = 11111₂ in the sentence l & 31

现在代码将5位值映射到其对应的7位ascii字符。这是棘手的部分,检查下表中小写
字母的二进制表示:

Now the code maps the 5-bit value to its corresponding 7-bit ascii character. This is the tricky part, check the binary representations for the lowercase alphabet letters in the following table:

  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

在这里你可以看到我们要映射的ascii字符以第7和第6位开头( 11xxxxx 2 )(除了空格,只有第6位),你可以 5位
编纂 96 96 10 = 1100000 2 )这应该足以进行映射,但是不适合空间(darn space!)

Here you can see that the ascii characters we want to map begin with the 7th and 6th bit set (11xxxxx₂) (except for space, which only has the 6th bit on), you could OR the 5-bit codification with 96 (96₁₀ = 1100000₂) and that should be enough to do the mapping, but that wouldn't work for space (darn space!)

现在我们知道必须特别注意与其他角色同时处理空间。为了达到这个目的,代码在
上打开第7位(但不是第6位)提取的5位组,OR 64 64 10 = 1000000 2 l& 31 | 64 )。

Now we know that special care has to be taken to process space at the same time as the other characters. To achieve this, the code turns the 7th bit on (but not the 6th) on the extracted 5-bit group with an OR 64 64₁₀ = 1000000₂ (l & 31 | 64).

到目前为止,5位组的格式为: 10xxxxx 2 (空格 1011111 2 = 95 10 )。
如果我们可以将空间映射到 0 而不影响其他值,那么我们可以打开第6位,这应该是全部。
这是 mod 95 部分发挥作用,空间是 1011111 2 = 95 10 ,使用mod
操作(l& 31 | 64)%95)只有空间返回 0 ,并且在此之后,代码通过将 32 10 = 100000 2
添加到上一个结果,((l& 31 | 64)%95)+ 32)将5位值转换为有效的ascii字符

So far the 5-bit group is of the form: 10xxxxx₂ (space would be 1011111₂ = 95₁₀). If we can map space to 0 unaffecting other values, then we can turn the 6th bit on and that should be all. Here is what the mod 95 part comes to play, space is 1011111₂ = 95₁₀, using the mod operation (l & 31 | 64) % 95) only space goes back to 0, and after this, the code turns the 6th bit on by adding 32₁₀ = 100000₂ to the previous result, ((l & 31 | 64) % 95) + 32) transforming the 5-bit value into a valid ascii character

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

下面的代码执行逆过程,给定一个小写字符串(最多12个字符),返回可以与OP代码一起使用的64位长值:

The following code does the inverse process, given a lowercase string (max 12 chars), returns the 64 bit long value that could be used with the OP's code:

public class D {
    public static void main(String... args) {
        String v = "hello test";
        int len = Math.min(12, 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);
    }
}    

这篇关于这怎么打印“hello world”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆