深入理解计算机系统-从书中看到了异或交换ab两个值的新感
还得从一个很经典的面试题说起:不通过第三个变量来交换两个变量a,b的值...
一个很经典的答案是通过异或来解决:
第壹步:a=a^b;
第贰步:b=a^b;
第叁步:a=a^b;
以前提起“异或”运算,真的很疑惑?

今天看到“布尔代数简介”,再次看到这个异或运算,才知道异或运算符"^"和“&”和“|”一个级别...
好吧,大家一起来温习下"~"、"&"、"|"、"^"...【0为假,1为真】
"~":对应逻辑运算NOT,非。{比如:~0=1或者~1=0},'~真'即假,'~假'即真;
"&":对应逻辑运算AND,这个大家一定都熟悉。[0]AND[0或者1]都为0,所以只有[1]&[1]=[1];一假即假;
"|":对应逻辑运算OR。[1]OR[0或者1]都为1,所以只有[0]|[0]=[0];一真即真;
"^":对应逻辑运算异或(XOR)。重点在"异",只有[1]XOR[0]或[0]XOR[1]才为1;一真一假即真;
布尔运算[&|^]和整数运算符[+-*/]有很多相同的属性。
由于"一真一假即真",所以0^0=1^1=0,扩展到二进制1111^1111=0000,并且1111^0000=1111,
想想一年级的加法运算(每位相加):
+ ------- =
所以:
^ ------------ =
所以a^a = 0, a ^ 0 = a ;
这下再讲异或交换两个变量就好理解了吧···
并且答案一般都是直接给异或过程的,就如刚开始那样,要不就是一边过程计算一边讲解,这样最多就是讲了每一步的原因,没讲到为什么要这样的步骤...
倒着推或许更好理解点,只要小学学会乘法/加法交换律就行了...
第0步:最后的结果就是a = b ,b = a ;
第1步:a = b ^ 0 = b ^ (a ^ a) = a ^ a ^ b; b = a ^ 0 = a ^ ( b ^ b) = a ^ b ^ b; (0为什么要消除?因为不能出现第三个变量啊,只能a和b)
第2步:发现上步a和b的最终形态都有a^b,先将a ^ b赋值给a或者b,大家貌似都是赋值给a了,咱也这样吧,(只能这么办了,不能第三个变量啊...) ;
a = (a ^ b) ;先求a的吧,a =a ^a ^b = a ^ a =0,,,,貌似不能先求a啊,再先试试来求b吧,如果b还求不出来,那么将a^b赋值给a是行不通的,
b = a^b^b=(a^b)^b=a^b(好吧,不为0,在重第0步开始看,能推到这步就行了;)
第3步:a =a^a^b;上步将a^b赋值给a了,(现在上步的a的作用还是类似第三个变量),上步将b=a了,所以a=a^a^b = a^b^a=(a^b)^a=a^b
(刚开始想的第二步刚开始a=a^b,然后b=a,那么a=a^b也改变值了,,把b当做引用类型了,自己把自己绕晕了...)
感觉最后两步讲的还是有点模糊,希望哪位大虾给完善下...
GG ... 晚安...
编辑二〇一六年十一月十五日 18:17:41

深入理解计算机系统-从书中看到了异或交换ab两个值的新感的更多相关文章
- 关于Vue中,使用watch同时监听两个值的实现方法
1. 先在computed中,用需要监听的两个值(start.end)定义一个对象(dateRange) computed: { dateRange () { const { start, end } ...
- 【转】《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误
原文地址:http://blog.csdn.net/slvher/article/details/9150597 对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构 ...
- 《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误
对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构成的模块跑起来后才出现内存崩溃,是很让人痛苦的.因为崩溃的位置在时间和空间上,通常是在距真正的错误源一段距离之后才 ...
- 深入理解计算机系统(2.8)---浮点数的舍入,Java中的舍入例子以及浮点数运算(重要)
前言 上一章我们简单介绍了IEEE浮点标准,本次我们主要讲解一下浮点运算舍入的问题,以及简单的介绍浮点数的运算. 之前我们已经提到过,有很多小数是二进制浮点数无法准确表示的,因此就难免会遇到舍入的问题 ...
- 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字
上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...
- 运用《深入理解Java虚拟机》书中知识解决实际问题
前言 以前看别人博客说看完<深入理解Java虚拟机>这本书并没有让自己的编程水平提高多少,不过却大大提高了自己的装逼水平.其实,我倒不这么认为,至少在我看完一遍这本书后,有一种醍醐灌顶的感 ...
- 《深入理解计算机系统V2》学习指导
<深入理解计算机系统V2>学习指导 目录 图书简况 学习指导 第一章 计算机系统漫游 第二章 信息的表示和处理 第三章 程序的机器级表示 第四章 处理器体系结构 第五章 优化程序性能 第六 ...
- 深入理解计算机系统(4.1)---X86的孪生兄弟,Y86指令体系结构
引言 各位猿友们好,计算机系统系列很久没更新了,实在是抱歉之极.新的一年,为了给计算机系统系列添加一些新的元素,LZ将其更改为书的原名<深入理解计算机系统>.这本书非常厚,而且难度较高,L ...
- 深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断
开篇请各位猿友允许LZ啰嗦几句,最近一直在写计算机系统原理这系列文章,也已经下定决心要把这本书的内容写完.主要目的其实是为了巩固LZ的理解,另外也想把这些内容分享给猿友们,毕竟LZ觉得这些内容对程序猿 ...
随机推荐
- http80端口转发(实现微信公众号接口绑定IP时,同时支持多个公众号)
http80端口转发 背景 微信公众平台接口绑定服务器时,如果使用IP需要使用80端口,此组件可实现一个IP上绑定多个公众平台接口 使用方法 http://(IP)/WeixinMP/(转发的地址Ba ...
- IIS配置错误信息输出
Asp.net: 一.通过 IIS 配置 1.打开IIS管理器,或按住 WIN + R 打开命令行输入 inetmgr 打开 IIS 管理 2.左边目录选择目标站点,在右边 IIS 块中双击 “错误页 ...
- MySQL备份原则
数据库备份遵守的原则: 定期对数据库进行备份 启用mysql服务器的二进制日志 备份文件命名既要有规律又要有意义 备份文件和数据库不要放在一个文件系统上 定期使用文件系统的备份功能来备份数据库的备 ...
- log4j属性详解
Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使用这三个组件可以轻 ...
- GoJS使用
1. 先学习官网的这篇Get Started with GoJS教程入门,了解GoJS基础知识: 2. 浏览GoJS各个示例(Samples.Intro),找到契合自己业务需要的某个或者某几个例子,然 ...
- java 和 mysql 获取周 星期 的第一天 最后一天 或者 月的 日期(字符串转日期,日期转字符串,日期加减)
获取周的第一天,最后一天 System.out.println(getStartEndDate("2016-05-01", 1)); 获取星期的第一天和最后一天 System.ou ...
- css中 Span 元素的 width 属性无效果原因及多种解决方案
先运行下程序看下: <span style='width:300px;'>123</span> 输出:123 可以看到 span会自动根据包含的内容来变化宽度 这是因为:对于内 ...
- C#中使用代码动态改变配置文件信息
static void Main(string[] args) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("../../App.co ...
- Github for Windows使用介绍
Git已经变得非常流行,连Codeplex现在也已经主推Git.Github上更是充斥着各种高质量的开源项目,比如ruby on rails,cocos2d等等.对于习惯Windows图形界面的程序员 ...
- Maven入门学习,安装及创建项目
一.maven介绍: 1.maven是一个基于项目对象模型(POM Project Object Model),通过配置文件管理项目的工具(项目管理工具). 2.maven主要功能:发布项目(从编译到 ...