很简单的shabby问题
- 很简单的shabby问题 推荐度:
- 相关推荐
很简单的shabby问题
C/C++带来的^运算符的问题
*************************************************************************************************************************************************
C/C++中的“^”是指平方,如2^3 = 8
Java中的“^”是指异或运算符,2^3 = 00...010^00...011 = 00...001 = 1
不要混淆,特别是在刷题中,Java要使用平方可以乘2次,如:x*x,也
可以使用 public static double pow(double a, double b)方法。
32位机器寻址能力:4GB
*************************************************************************************************************************************************
计算误区:2^32 = 2^22 * 2^10= 2^22Gb = 2^14 * 2^8 * Gb = 2^14 GB
原因:不知道你为什么直接就有:G = 2^10b
实际上:k = 2^10,M = 1024 * k = 2^20,G = 1024 * M = 2^30
所以,2^32 = 4* 2^30 = 4 G
那么B是哪里来的???
还是说已经规定了内存是按字节(B)编址的了?
计算机中负数补码为原码+1【1】
*************************************************************************************************************************************************
eg 16位机器中:
正数三码合一:
5 的原码:0000 0000 0000 0101
5 的反码:0000 0000 0000 0101
5 的补码:0000 0000 0000 0101 负数有区别:
-3 的原码:1000 0000 0000 0011
-3 的反码:1111 1111 1111 1100 //注意符号位不变
-3 的补码: 1111 1111 1111 1101 //注意符号位不变
而在计算机中加法不用说,直接加。减法在真正计算中都是转化为+补码的形式计算:
5 - 3 = 5 + ( -3 )
0000 0000 0000 0101 + 1111 1111 1111 1101 = 1 0000 0000 0000 0010
那么首先
① 为什么都转化为加法运算呢,因为CPU只有加法器,为什么CPU不设计减法器呢,我觉得除去设计难度(即假设可以实现,有待探讨减法器的可行性),从数学/哲学上说,减一个数和加这个数的相反数其实是一样的。
② 在现有的补码计算规则下,减法转化为加补码的原理(正确性)如何保证)?
可以确定的是,正确性已经包含在补码的计算规则中,应该是先有加补码的idea,再有补码的计算规则,这和C语言的变量命名规则——只能下划线,数字和字母组成并且开头不能为数字一样,应该是先设计常量的命名规则,然后再在它的余集中选取变量的命名规则是一样的,先想下蛋,才有鸡嘛:)
现在要搞清楚的是,加补码的结果是正确的。下面证明。
1)先感性认识一下,考虑这样一个问题:有一块钟表的快了两个小时(假设现在钟表2点),怎么将其恢复正常?
最直接的方法肯定是直接将时针往回拨2小时,但是还有一个方法:
将时针往前拨12-2 = 10个小时。
即对于表盘而言, - n = + 12 - n (0< = n <= 12)。
同样地,对于大于12的n值,可以使用取余(取模)解决这个问题:- n = + (-n)%12 (n >= 0 )(其实[0,12]是特例而已),可以看到,-2,-14,-26 ...%12 = 2,即往回拨2,14,26...小时效果和往前拨10小时都是一样的,这和实际的经验吻合。
上面是12进制的问题,现在将问题拓展,考虑整数n∈[0,1 0000 0000 0000 0000](二进制)之间的减法问题:
减n = 加上对-n求128的余
-n = + 1 0000 0000 0000 0000 - n = + 0000 0000 0000 0001 +1111 1111 1111 1111 - n
=+ 1 + (-n)的反码
= (-n)的补码
-n的补码就是对-n求1 0000 0000 0000 0000 的余 !
不过,上面有两个小细节:
1)1111 1111 1111 1111 - n = (-n)的补码
如果直接从负数的反码来考虑,好像并不是1111 1111 1111 1111 - n,而是1 0 1111 1111 1111 1111 - n,因为负数的符号位没有变。但是这里n为正数,是直接从+n原码求-n反码的,例如求-3反码的过程:+3原码:0000 0000 0000 0011—— -3原码:1000 0000 0000 0011—— -3反码:1111 1111 1111 1100,如果掐去中间过程:
+3原码:0000 0011—— -3反码:1111 1111 1111 1100
是不是就是1111 1111 1111 1111 - 0000 0000 0000 0011 ?
2)正数只到127的情况下,减128不会出问题?
另外,为了简单考虑,考虑一下8位二进制,对于-128,其实并没有超出范围,回到钟表例子,正数范围是1,...,11,12,如果从0开始数,则是0 ... 11。但是求余法则一样适用于“回拨12小时”的情况,因为求余的底数用的是12...所以数为[0,127],而支持的减法可以减到128,故8位二进制可以支持的最小负数可以到-128。
证法二:
踏实计算,证明真正的减法过程和加补码是一样的:正确性蕴含在补码的求取规则中。
假设A,B均正,且符号位参与运算,直接运用十进制减法规则:低位直接相减,不够向高位借位,则
a. |A| >= |B|,则最高位不需要借位,符号位0-0=0,正确,即|A| >= |B|时,可以直接将符号位参与运算,不影响结果,但是为不涉及具体计算过程(真的进行数值部分减法),可以这样看:
|A| - |B| = |A| + 1111 1111 1111 1111 - |B| - 1111 1111 1111 1111
= |A| + (-|B|)反码 - 1111 1111 1111 1111
= |A| + (-|B|)反码 +1 - 1111 1111 1111 1111 - 1
= |A| + (-|B|)补码 - 1 0000 0000 0000 0000
(也可以使用|A| + 1 0000 0000 0000 0000 - |B| - 1 0000 0000 0000 0000 直接推)
由于|A|,|B|为-128 ~ 127 之间的数,循环周期为 256 = 1 0000 0000 0000 0000,故
|A| - |B| 的最终结果 - 1 0000 0000 0000 0000相当于 -1 -1 -1 ... -1退回256步,回到原点。
或者从这个结论出发,|A| - |B| = |A| - |B| + 1 0000 0000 0000 0000 = |A| + (-|B|)补码
b. |A| < |B|, 数值部分不够用,要借位,最高位前面是符号位,向符号位借一位,但是符号位为0,只能向“虚空”借一位(+ 1 0000 0000 0000 0000),这样刚好符号位也正确了(剩下了一个1 -0 =0),数值部分也够用了,故等效+1 1000 0000 0000 0000参与运算:
|A| - |B| = |A|原码 + 1 0000 0000 0000 0000 - |B|原码
= |A|原码 + 0000 0000 0000 0001 +1111 1111 1111 1111 - |B|原码
= | A|原码 + 1 + (-|B|)的反码
=|A|原码 +(-|B|)的补码
综上,A-B = |A| + (-|B|)补码
以后证明,不用分大小讨论,直接用|A| - |B| = |A| - |B| + 1 0000 0000 0000 0000 = |A| + (-|B|)补码,从这个角度来看,其实还是用到了 “减法——>加上周期取余” 的转化方法,将减法的过程移到求补码的过程中去。
所以|A| - |B| = |A| - |B| + 1 0000 0000 0000 0000 = |A| + (-|B|)补码的证明方法兼具两种证法的优点——原理简明,过程严瑾。
参考资料:
【1】
最新文章
- python len ljust
- phpcms api接口开发
- 大连伟世帮您留学
- 关于使用ComponentName连接俩个Activity运行闪退的问题
- Maven的三种packaging方式(pom、jar、war)
- SOA教程之:SOA的优点和缺点
- FPGA设计中,产生LFSR伪随机数
- 看门狗watchdog的理解
- 前途迷茫不知.NET与JAVA那个好
- 综合案例:选餐
- clion之Clion License Activation破解
- Linux C编程itoa()函数 atoi()函数
- atoi和itoa(头文件stdilb.h)的C实现
- 微信小程序多个倒计时
- 微信开发之小程序实现倒计时
- curl命令详解 (实例使用方法)
- 基于直方图的图像增强算法(HE、CLAHE)之(二)