part 1 .问题的由来:老师上课布置了这样一道题,“char m=(int)a,请问这个a输入怎样的一个负整数才能使m在按照字符格式输出时,输出 'b' ?”
part 2. 预备知识:
①在java中,int类型是占用4字节,即32位二进制,按照补码形式存储;char类型是2字节,即16位二进制,按照原码形式存储。(因此int类型是要比char类型多16位的,这就会产生一个数值位丢失的问题...嘶~如何解决?)
②多了16位,那就丢16位嘛。当int类型强转位char类型时,会将该变量(或者是立即数,就是手动输入的整数)对应的32位补码中,高16位舍去,剩余16位作为强转之后的char类型变量的原码
③该char类型变量得到原码之后,计算机对照unicode集,输出对应的字符
part 3. 正式解题:“char m=(int)a,请问这个a输入怎样的一个负整数才能使m在按照字符格式输出时,输出 'b' ?”
①字符'b'对应的unicode码为:98,对应的16位原码为0000 0000 0110 0010
②若想一个整形负数强转为char类型后,输出'b',那么这个负数的 补码的 低16位应该为:0000 0000 0110 0010
(补充知识点:补码的运算,假设一个二进制整数x,有8位(4位,16位的处理方法与8位基本相同)
---->x为正:假设为+0110 1101,那么它的补码就是:把它真值前面的 加号 变成0 即可
[x]补= 0 0110 1101
--->x为负:假设为-0110 1101,那么它的补码就是:把它的负号变成1,剩余的数值位取反加1
[x]补= 1 1001 0011
这里只是大致讲述一下 接下来会用到的 补码运算法则,更多细节请 读者亲亲 自己在csdn上搜索,会有更多细节哦 )
继续解题哈。。。
③已经知道该 整形变量的 补码的 低16位是:0000 0000 0110 0010,那么其高16位呢?
因为这里要舍去高16位,所以这里肯定不能让高16位全为0,这样不就是求一个正的整形变量嘛;
所以,这个高16位的 有效部分的 首位一定是1,因为1表示这个补码是负数补码;
接着,假设 高16位的 最高位为1,即:1~~~ ~~~~ ~~~~ ~~~~,剩余工作就是把这些未知的'~'填入0或者1就好了;(首位的1表示为负数,剩余为数值位,因为这个高16位只要存在即可,反正都要舍去,所以这15个'~'就是随便填啦;也因此,可以输出'b'的整形负数 为 2^15 个,数学原理 不再解释了哈)
最后,随意假设高16位为:1000 0010 1000 0011,结合低16位可得该整形负数的 补码为:---->
[x]补=1000 0010 1000 0011 0000 0000 0110 0010
则x= -0111 1101 0111 1100 1111 1111 1001 1110
科学计算器可得:x=-2105343902
最后的最后!!!
为什么写的这么详细呢?
因为我的眼里饱含热泪!!~~~
各位 于晏!!!各位热巴!!!
给个三连吧~~~!!!