美文网首页
【谜题】十六进制之谜

【谜题】十六进制之谜

作者: 实训邦小姐姐 | 来源:发表于2018-11-05 10:43 被阅读26次

16进制常量用于计算机领域的一种重要的数制。

程序里面的任何一样东西都有一种称呼,例如:数据类型、变量、常量、类、函数等等

在程序里面,为基本数据类型赋值的结果值被称之为字面常量,例如,int a = 10;这个10被称之为字面常量

下面的程序是对两个十六进制(hex)字面常量进行相加,然后打印出十六进制的结果。这个程序会打印出什么呢?

public class JoyOfHex{

    public static void main(String[] args){

        System.out.println(

          Long.toHexString(0x100000000L + 0xcafebabe));

    }

}

看起来很明显,该程序应该打印出1cafebabe。毕竟,这确实就是十六进制数字10000000016与cafebabe16的和。

该程序使用的是long型运算,它可以支持16位十六进制数,因此运算溢出是不可能的。

然而,如果你运行该程序,你就会发现它打印出来的是cafebabe,并没有任何前导的1。这个输出表示的是正确结果的低32位,但是不知何故,第33位丢失了。

看起来程序好像执行的是int型运算而不是long型运算,或者是忘了加第一个操作数。这里到底发生了什么呢?

十进制字面常量具有一个很好的属性,即所有的十进制字面常量都是正的,而十六进制或是八进制字面常量并不具备这个属性。

要想书写一个负的十进制常量,可以使用一元取反操作符(-)连接一个十进制字面常量。

以这种方式,你可以用十进制来书写任何int或long型的数值,不管它是正的还是负的,并且负的十进制常数可以很明确地用一个减号符号来标识。

但是十六进制和八进制字面常量并不是这么回事,它们可以具有正的以及负的数值。

如果十六进制和八进制字面常量的最高位被置位了,那么它们就是负数。在这个程序中,数字0xcafebabe是一个int常量,它的最高位被置位了,所以它是一个负数。它等于十进制数值-889275714。

该程序执行的这个加法是一种“混合类型的计算”(mixed-type computation):左操作数是long类型的,而右操作数是int类型的。

为了执行该计算,Java将int类型的数值用拓宽原始类型转换提升为一个long类型,然后对两个long类型数值相加。

因为int是一个有符号的整数类型,所以这个转换执行的是符合扩展:它将负的int类型的数值提升为一个在数值上相等的long类型数值。

这个加法的右操作数0xcafebabe被提升为了long类型的数值0xffffffffcafebabeL。这个数值之后被加到了左操作数0x100000000L上。

当作为int类型来被审视时,经过符号扩展之后的右操作数的高32位是-1,而左操作数的高32位是1,将这两个数值相加就得到了0,这也就解释了为什么在程序输出中前导1丢失了。

   1111111

  0xffffffffcafebabeL

+ 0x0000000100000000L

---------------------

  0x00000000cafebabeL

用手写的加法实现,在加法上面的数字是进位

订正该程序非常简单,只需用一个long十六进制字面常量来表示右操作数即可。这就可以避免了具有破坏力的符号扩展,并且程序也就可以打印出我们所期望的结果1cafebabe:

   public class JoyOfHex{

    public static void main(String[] args){

        System.out.println(

          Long.toHexString(0x100000000L + 0xcafebabeL));

    }

}

混合类型的计算可能会产生混淆,尤其是十六进制和八进制字面常量无需显式的减号符号就可以表示负的数值。

为了避免这种窘境,通常最好是避免混合类型的计算。

对于语言的设计者们来说,应该考虑支持无符号的整数类型,从而根除符号扩展的可能性。

可能会有这样的争辩:负的十六进制和八进制字面常量应该被禁用,但是这可能会挫伤程序员,他们经常使用十六进制字面常量来表示那些符号没有任何重要含义的数值。

参考资料:

http://www.cnblogs.com/yuyu666/p/9840329.html

https://blog.csdn.net/qq_33757398/article/details/81286242

                                                      ———— / END / ————

我会长成大树,等你赞声良木。  

相关文章

  • 【谜题】十六进制之谜

    16进制常量用于计算机领域的一种重要的数制。 程序里面的任何一样东西都有一种称呼,例如:数据类型、变量、常量、类、...

  • 蒙娜丽莎上的达芬奇密码,向我们传达什么信息?

    《蒙娜丽莎》的故事说不完,今天和大家分享最后两个谜题:字符之谜和真伪之谜 废话不多说,先上总纲: 六.字符之谜 蒙...

  • 浅谈西方心理学发展史——学习戴维▪霍瑟萨尔《心理学史【第4版】(

    一、西方心理学的起源 说到起源这个词,这里有世界的三大终极谜题与起源相关:物质起源之谜、生命起源之谜和意识起源之谜...

  • 扑克牌之谜题

    这题没有投机取巧,却巧妙令我折服。 且看看你能做吗? 若不能,给你答案之后,你明白那个答案之有理吗? 如果明白,你...

  • 世界未解之谜之谜题难解(2019)

    伊丽莎白为何终身不嫁 伊丽莎白的统治时期是英格兰趋向强盛和国家建立最重要的一个时期。此时英国经济发展、文化繁荣,拥...

  • 世界未解之谜之谜题难解(2019)

    马可.波罗究竟有没有到过中国 (一部书,第一次为西方人开启东方之门,让很多欧洲人几个世纪以来一直心怀东方情结。然而...

  • 二分查找之谜题

    1 前言 二分查找本身是个简单的算法,但是正是因为其简单,更容易写错。甚至于在二分查找算法刚出现的时候,也是存在b...

  • 心耳切切——湖之谜题(71)

    置身于湖上,湖面明净如镜,水中倒映着森林与天空。森林独有的幽静气息和微波是它的脉动。 仰面向天空,于湖中...

  • Java谜题5 - 十六进制的趣事

    下面的程序是对两个十六进制(hex)字面常量进行相加,然后打印出十六进制的结果。这个程序会打印出什么呢? 看起来很...

  • 不该这样

    那些不堪回首的过去 变成一个局 是谁出的谜题 至今还是未解之谜 你患得患失 找不到属于你的位...

网友评论

      本文标题:【谜题】十六进制之谜

      本文链接:https://www.haomeiwen.com/subject/vbgjxqtx.html