# zb_java0719 **Repository Path**: linmumumu/zb_java0719 ## Basic Information - **Project Name**: zb_java0719 - **Description**: 计算机基础补充:原码、反码、补码 运算符 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 16 - **Created**: 2018-07-19 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # zb_java0719 # 教学目标 1.计算机基础补充:原码、反码、补码 2.运算符 # 课堂笔记 ## 计算机基础:原码、反码、补码 原码、反码、补码主要是计算机中二进制对负数的兼容; 1.原码 使用二进制表示一个数就是这个数的原码; 计算机二进制中的负数的表示,采用最高位(最左侧)作为符号位,1表示负数,0表示整数; 正数的原码就是其二进制的数; 负数的原码: 将负数的绝对值使用二进制表示以后,将最高位变为1,这就是负数原码; 例如: -3 原码: 1000 0011 因为cpu只会进行加法运算,所以需要将减法变为加法,但是计算机使用原码进行运算时,运算结果是错误的; 例如: 2-5 转换加法 2+(-5) 这时,用原码进行计算,结果是错误的; 2 原码 0000 0010 -5 原码 1000 0101 相加 1000 0111 原码结果是 -7 基于以上原因: 提出了补码的概念,补码的作用就是将减法转换为加法进行运算; 补码求法: 正数的补码和原码一样。 负数的补码:原码的最高符号位不变,其他各位取反+1; 求法二:反码+1; 补充:负数的补码继续进行求补运算得到是原码; 反码: 存在价值:为了求补码,是一个中间过程值。 正数的反码和原码一样; 负数的反码:原码的最高符号位不变,其他各位取反; 示例:运用补码计算 2-5 2 原码 0000 0010 补码 0000 0010 -5 原码 1000 0101 补码 1111 1011 进行加法运算 1111 1101 (计算结果还是补码) 还原为原码: 1000 0011 (原码:-3) ###### 定律:计算机中所有的数都是以补码的形式存在的。【计算机中的负数是以补码的形式存在的】【正数的原码、反码、补码一样】 ## 3 位运算符 ### 3.4 移位运算 是对二进制的数的每一位进行运算;(参与运算的数是二进制中的位bit) 运算符: ~ & | ^ >> << >>> 语法: << 左移运算:最高位符号位不变,其他各位向左移动N位,右侧空余的位数补0; 等价于:该数*2的N次方; >> 右移运算:最高符号位不变,其他各位向右移动N位,左侧空余位数补符号位;【符号位是0补0,符号位是1补1】 等价于:该数/2的N次方; >>>带符号位的右移:最高符号位也参与移位,所有位数全部向右移动N位,左侧空余位数补0; 等价于:该数/2的N次方;注意,该运算只对正数有意义,对负数没有意义; 位移运算效率要比运算乘法、除法效率高; 代码[com.yuw.ch2.opt.Test01]: ```java /** * 位移运算 */ private static void test01() { // 定义一个变量 int iVal10 = 3; int iVal20 = 128; // 左移运算 int iVal11 = iVal10 << 3;// 等价于 iVal*2的3次方 24 System.out.println("iVal10<<3:" + iVal11); // 右移运算 int iVal21 = iVal20 >> 3; // 等价于 iVal21/2的3次方 System.out.println("iVal20>>3:" + iVal21); } ``` 位运算应用:采用异或位运算交换两个数的值。【优点:不需要借助第三个临时变量】 代码[com.yuw.ch2.opt.Test01]: ```java /** * 位运算应用:不借助第三个变量,交换两个变量的值 */ private static void test02() { int i = 2; int j = 3; System.out.println("交换前:i=" + i + ",j=" + j); // 交换两个变量的值 i ^= j; j ^= i; i ^= j; System.out.println("交换后:i=" + i + ",j=" + j); } /** * 位运算应用:借助第三个变量,交换两个变量的值 */ private static void test021() { int i = 2; int j = 3; System.out.println("交换前:i=" + i + ",j=" + j); // 交换两个变量的值 // 定义一个临时变量 int temp = i; i=j; j=temp; System.out.println("交换后:i=" + i + ",j=" + j); } ``` ## 4 逻辑算符 ### 4.1 逻辑运算语法 逻辑运算的运算符: ! && || 逻辑运算的操作数是布尔类型; 逻辑运算的结果也是布尔类型; 逻辑运算优先级: 非>与>或 !运算:一元运算符 true 变 false false 变 true &&与运算:二元运算符 T && T = T T && F = F F && T = F F && F = F 总结:只有两个操作数都为T时,才为T,其他情况为F; ||或运算:二元运算符 T || T = T T || F = T F || T = T F || F = F 总结:只有两个操作数都为F时,才为F,其他情况为T; 代码[com.yuw.ch2.opt.Test01]: ```java /** * 逻辑运算 */ private static void test03() { // 定义变量 int i0 = 0; int i1 = 1; int i2 = 2; boolean isOk1 = ++i0 > i1++ && ++i1 > i2; // false i0=1; i1=3 i2=2 System.out.println("isOk1=" + isOk1); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2); // 发生了逻辑短路 } ``` ### 4.1 逻辑运算短路 逻辑短路: 当多个表达式进行连续的与运算时,从左往右如果某个表达式的结果是false,则与运算结果为false, 同时该表达式之后的表达式不再参与运算,这就是逻辑与短路。 逻辑或短路: 当多个表达式进行连续的或运算时,从左往右如果某个表达式的结果是true,则整个或运算结果为true, 同时该表达式之后的表达式不再参与运算,这就是逻辑或短路。 混合逻辑短路: 逻辑与和逻辑或进行运算时,可以在与运算或者或运算都发生逻辑短路; 代码[com.yuw.ch2.opt.Test01]: ```java /** * 逻辑运算 */ private static void test03() { // 定义变量 int i0 = 0; int i1 = 1; int i2 = 2; boolean isOk1 = ++i0 > i1++ && ++i1 > i2; // false i0=1; i1=2 i2=2 // 发生逻辑与短路 System.out.println("isOk1=" + isOk1); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2); // 发生了逻辑短路 System.out.println("==========================="); // 重新初始化赋值 i0 = 0; i1 = 1; i2 = 2; // 或短路 boolean isOk2 = ++i0 >= i1++ || ++i1 > i2; // true i0=1; i1=2 i2=2 // 发生逻辑或短路 System.out.println("isOk2=" + isOk2); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2); // 发生了逻辑短路 System.out.println("==========================="); i0 = 0; i1 = 1; i2 = 2; int i3 = 4; int i4 = 5; // 1+1+1+1+1+2+3+3*4+4*5 从左往右开始执行 // 混合逻辑短路 F T T T(发生短路) boolean isOk3 = ++i0 > i1++ || ++i1 > i2 && i4 > i3++ || ++i3 > i4++ || i4 > i3 && i3-- > --i4; // true // i0 =1 ,i1=3, i2 = 2,i3 =5 ,i4 = 5 System.out.println("isOk3=" + isOk3); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2 + ",i3=" + i3 + ",i4=" + i4); // 发生了逻辑短路 // 从左往右 boolean isOk4 = (++i0 > i1++ || ++i1 > i2) && i4 > i3++; } ``` ## 5 表达式运算优先级 记住:教材P38页表; 自增、自减 > 乘除求余 > 加减 > 位移 > 比较运算 > 位运算 > 逻辑运算 > 赋值运算 #### 参与贡献 1. Fork 本项目 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [http://git.mydoc.io/](http://git.mydoc.io/) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)