windows自带的计算器(简称calc),默认的操作数是64位的,第63位(从0开始数)表示操作数的符号,1表示负数,0表示正数。
calc默认进行64位有符号数的四则运算,并且以补码的形式显示运算结果。
因此,对于8位有符号数之间的四则运算,calc会自动理解成无符号数进行运算。
如0x80*0x2,calc会理解成0x0000000000000080*0x0000000000000002进行运算,得到的结果是0x100。
然后,我们的目的,是希望计算器理解成-128*2=-256,最终显示结果为0x8100(16位有符号数,原码)
原码、反码及补码的关系如下:
(正数)原=(正数)反=(正数)补
(正数)原=(~正数)反=(~正数+1)补
~正数为除最高位符号位外,其他位全部取反。
了解到这些之后,我们来用calc实现8位有符号数之间的四则运算0x80*0x2。
1.将calc选择到十六进制,输入80
2.将calc选择到十进制,这时显示为128,单击+/-键,将128转化成-128
3.再次将calc选择到十六进制,回到十六进制模式,单击*,表示进行乘法操作
4.输入2,单击=号,得到运行结果0xFFFFFFFFFFFFFFF0
一个很长的数,别被它吓到了,它其实是-256的64位补码形式。根据前面介绍的原码、反码及补码的关系,我们很容易将它转化成64位原码形式0x8000000000000100.
步骤如下:
1.在显示0xFFFFFFFFFFFFFFF0的界面下,单击-键,输入1,得到结果0xFFFFFFFFFFFFFEFF(反码)
2.单击Not键,得到原码0x100,注意,此处是对全部位都取反了,实际上我们要保留最高位符号位不变,因此,在0x100基础上,再加上符号位,最终得到原码0x8000000000000100.
从最后一步的操作可以看出,我们得到了最终结果0x100以后,可以将这个结果理解成任意位的符号数了,只要在相应的符号位上加上1,就得到了最终的原码。比如将0x100理解成16位有符号数,则原码为0x8100,若理解成32位有符号数,则原码为0x80000100。
虽然麻烦,不过,最终我们计算出来所期盼的结果,通过这个简陋的计算器。