对于计算机来说,加减乘除法全部用二进制来实现,那么他们是如何实现的呢?
先说加法,加法有两种,其实区别不大只是解释方式不同,原码加法(无符号)和补码加法(有符号,加完依然是补码)。方法都一样,有一落一,无一落零,两一进位。但这样必须考虑溢出的问题,对于32位机,所有数都用32位来表示,加法可能会向前进一位,也就是最多有33位,怎么办? 33位数无法表示,其实很简单,对于原码加法,只要溢出了,那么最高位一定是一,表示的结果会把最高位的一强行截掉,这样实际上我们看到的值就是(正确值-2^32)得到的。那么补码加法就比较麻烦了,多了个符号位,所以可以分情况讨论:1、正负得负,2、正负得正,3、正正得正,4、负负得负。前两种溢出无影响(很容易就可以得出结论); 第三种溢出之后显示的结果必然是正确值相对于无符号最大数的补数;第四种情况自己总结吧 =。=
减法涉及不到溢出,使用加法来实现的,写起来比较麻烦,自己想想吧。
乘法,先说说溢出吧,乘法的溢出是很恐怖的,一般情况下,由于位宽不变,超出位宽的数要全部被截掉,然后给你显示出来,这个显示出来的数和正确值是有关系的,显示的数=正确值%正数最大值(比如32位 2147483648)。再说说乘法效率的问题,如果给他们排个序,一定是这样的 加法《减法《乘法《除法 。 可以毫不夸张地说,乘法的运算效率比加法低十几倍! 那怎么办呢? 总不能不用乘法吧, 为此很多编译器都做了优化,因为乘一个数,总能转换成左移和加减法的组合运算,从而降低复杂度,比如x*14,可以转化成 (x<<3)+(x<<2)+(x<<1) 也可以写成 (x<<4)-(x<<1)。为什么呢? 看看14的二进制码就知道了,1110! 没错第一种形式和快速幂的原理差不离。第二形式可以作为一个延伸。
除法,除法就更慢了,而且还有除不开取整的情况,负数向后取整(-3.14 取整 -4),正数向零取整(3.14 取整 3),哦对,编译器已经规避了这种非习惯性的取整方式(方法是对负数除法是加上一个偏移量), 除法并没有什么优化方法,没有乘法的那种规律,所以他很慢,真的很慢,能不用就不用吧。