主要内容 #
减法运算的不同之处 #
上节课中,我们讲了加法的运算过程,大家是否好奇,减法是怎么处理呢?是不是和加法一样呢?
现在,基于大家现在掌握的知识,我们可以正式谈一谈,负数(减法)要怎么处理。
大家可以先思考一下,假如你就是计算机,你会怎么处理下面的运算呢?
十进制数: 10 - 1 = 9 || || \/ 二进制数: ?????
减法运算推导 #
在计算机中,我们其实是这样处理的
十进制数: 10 - 1 = 9 || || \/ 十进制数: 10 + -1 = 9 || || \/ 二进制数: 1010 + (负的0001)= 1001
大家可以想一想,(负的0001)应该是多少呢?还记得我们讲过的“符号位”吗?
二进制数: 1010 + (负的0001)= 1001 0000 1010 + (1000 0001) // char =1000 1011 = -11(10进制) =/= 9(10进制)
怎么不对呢?
负数在内存中的确是 (1000 0001) ,其实问题出在加法的计算过程中。
- C++ 中,正负数直接相加的结果,并不能得到正确的减法结果。这是因为“符号位1”是人为约定的,不符合一般的数学运算规则。
我们来推导一下,到底需要怎么计算。
二进制数: 1010 + (负的0001)= 1001 1010 + X = 1001 假定,使用 char 类型,那么内存大小就是 8 bits X = 0000 1001 - 0000 1010 X = 1 0000 1001 - 0000 1010 // 被减数 借位 1 0000 1001 - 0 0000 1010 ----------------- X = 0 1111 1111 X 最后保留 char 的 8 bits X = 1111 1111
诶!出来了一个很奇怪的数据,不是吗?
小结 #
上述的运算,最终是这样进行的
十进制数: 10 - 1 = 9 10 + -1 = 9 二进制数, char 类型: 0000 1010 + (1111 1111) // 【最关键步骤,称为“转化成补码”】 0000 1010 + 1111 1111 ----------------- = 1 0000 1001 仅仅保留最低 8 bits = 0000 1001 = 9(10进制)
补码 #
所谓“码”,就是内存中的那个二进制值。
所以,上一节中的“原码”,就是表示数值在内存中的那个二进制。
所谓“补码”,就是专门用于“减法计算中”,负数的表示。
- 注意,“补码”,就是专门用于“减法计算”
怎么计算补码 #
原码为正数: 补码 = 原码 原码为负数: 补码 = 反码 + 1 // 反码见下面说明 原码为零: 补码 = 0
反码 #
原码为正数: 反码 = 原码 原码为负数: 反码 = 原码的基础上, 符号位不变,其余各个位取反
所以,请特别注意减法的特殊处理。