布尔代数上的位运算

布尔代数是一个数学知识体系,它在0和1的二进制值上演化而来的。

我们不需要去彻底的了解这个知识体系,但是里面定义了几种二进制的运算,却是我们在平时的编程过程当中也会遇到的。这四种运算分别是或、与、非和异或。下图展示了在布尔代数的知识体系中,对这四种运算的定义。

从左至右依次是非、与、或以及异或。这个图阐述的是针对一位二进制的运算结果,我们可以将其扩大到N位二进制。比如两个二进制[aw,aw-1...a1]和[bw,bw-1...b1],它们的四种运算则是对两者每一个相对应的位上做相应的运算。

也就是说,倘若假设结果是[cw,cw-1...c1]的话,那么对于任意ci都满足 ci = ai (|,&,^) bi,如果是对[aw,aw-1...a1]进行非运算的话,那么ci = ~ai。

C语言上的位运算

 

在C语言中,也支持位运算,而它的计算方式就是布尔代数中的位运算。位运算我们最常使用的是掩码的方式。比如我们知道一个整数x,如果我们想取得这个整数的最后一个字节的整数值的话,就可以采用位运算。就像下面这样。

#include <stdio.h>

int main(){
unsigned int i = 0x12345678;
unsigned int j = 0xFF;
unsigned int k = i & j;
printf("%X\n",k);
}

最终我们希望得到的结果是78,也就是整数i的最后一个字节的值,我们使用掩码0xFF以及与运算过滤掉整数i的高位的三个字节。以下是结果。

C语言的逻辑运算

C语言中的逻辑运算有||、&&和!,这比较容易与刚才的|,&和~搞混。逻辑运算比较特别,在这种运算的结果中认为所有非0的数值都是true,而为0的则为false。LZ在此写了一个小程序,我们来简单的看下二者的区别。

#include <stdio.h>

int main(){
unsigned int x = 0x12345678;
unsigned int i = !x;
unsigned int j = ~x;
unsigned int m = !!x;
unsigned int n = ~~x;
printf("%u %u\n",i,j);
printf("%u %u\n",m,n);
}

从这个程序的结果可以很明显的看出!和~运算的区别,我们来直接看结果吧。

结果很明显,左边是!x以及!!x的结果,只有0和1,而右边则是~x和~~x的结果。这里可以很明显的看出逻辑非与位的非运算的区别。前者只有0和1,而后者则是对每一位二进制值取反。

除了结果上的区别之外,它们二者还有一个区别,就是逻辑运算倘若可以根据第一个表达式确定结果的话,那么将不会计算第二个表达式。举个简单的例子,假设有两个表达式a和b,对于a && b,倘若a为假,则不会计算b表达式的值。但是对于a & b则不同,无论a表达式的值为何,都要计算b表达式的值。

C语言的移位运算

移位运算分为两种,左移和右移。对于一个二进制数[aw,aw-1,...a1]来说,如果将它进行左移运算,则x << k = [aw-k,aw-k-1,...a1,0,...0]。此时相当于最高的那k位都被丢弃了,在最右端补了k个0。而对于x >> k来说,也就是右移运算,与左移是类似的,只不过为了照顾有符号数,有时候需要在左端补最高位而不是0。而对于补0的情况,则称为逻辑右移,补最高位的则称为算术右移

也就是说,对于逻辑右移来说,x >> k = [0,...0,aw,aw-1,...ak+1],而对于算术右移来说,x >> k = [aw,...aw,aw,aw-1,...ak+1]。

本章小结

本章主要只是简单的介绍了下C语言中的位运算,下一章将会介绍一下整数的表示方式。

深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算的更多相关文章

  1. 深入理解计算机系统(2.5)------C语言中的有符号数和无符号数以及扩展和截断数字

    上一篇博客我们讲解了计算机中整数的表示,包括无符号编码和补码编码,以及它们之间的互相转换,个人觉得那是非常重要的知识要点.这篇博客我们将介绍C语言中的有符号数和无符号数以及扩展和截断数字. 1.C语言 ...

  2. 深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断

    开篇请各位猿友允许LZ啰嗦几句,最近一直在写计算机系统原理这系列文章,也已经下定决心要把这本书的内容写完.主要目的其实是为了巩固LZ的理解,另外也想把这些内容分享给猿友们,毕竟LZ觉得这些内容对程序猿 ...

  3. 深入理解计算机系统(2.3)------布尔代数以及C语言运算符

    本篇博客我们主要讲解计算机中的布尔代数以及C语言的几个运算符. 1.布尔代数 我们知道二进制值是计算机编码.存储和操作信息的核心,随着计算机的发展,围绕数值0和1的研究已经演化出了丰富的数学知识体系. ...

  4. 《深入理解计算机系统》【PDF】下载

    <深入理解计算机系统>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382303 内容提要 本书主要介绍了计算机系统的基本概念,包 ...

  5. 深入理解计算机系统 (Randal E.Bryant / David O'Hallaron 著)

    第1章 计算机系统漫游 (已看) 1.1 信息就是位+上下文 1.2 程序被其他程序翻译成不同的格式 1.3 了解编译系统如何工作是大有益处的 1.4 处理器读并解释存储在内存中的指令 1.4.1 系 ...

  6. 《深入理解计算机系统V2》学习指导

    <深入理解计算机系统V2>学习指导 目录 图书简况 学习指导 第一章 计算机系统漫游 第二章 信息的表示和处理 第三章 程序的机器级表示 第四章 处理器体系结构 第五章 优化程序性能 第六 ...

  7. 深入理解计算机系统(4.1)---X86的孪生兄弟,Y86指令体系结构

    引言 各位猿友们好,计算机系统系列很久没更新了,实在是抱歉之极.新的一年,为了给计算机系统系列添加一些新的元素,LZ将其更改为书的原名<深入理解计算机系统>.这本书非常厚,而且难度较高,L ...

  8. 深入理解计算机系统(1.2)---hello world的程序是如何运行的

    在写本章的内容之前,LZ先做个小广告.其实也不算是什么广告,就是LZ为了和各位猿友交流方便,另外也确实有个别猿友留言或者在博客里发短消息给LZ要联系方式.因此LZ斗胆建立了一个有关<深入理解计算 ...

  9. 《深入理解计算机系统》 Chapter 7 读书笔记

    <深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...

随机推荐

  1. 【hbase】——HBase 写优化之 BulkLoad 实现数据快速入库

    1.为何要 BulkLoad 导入?传统的 HTableOutputFormat 写 HBase 有什么问题? 我们先看下 HBase 的写流程: 通常 MapReduce 在写HBase时使用的是 ...

  2. 烂泥:nginx同时支持asp.net与php

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 经过两天的实验,终于让nginx同时支持asp.net与php了.下面就把具体的配置过程记录如下. 注意:本次实验OS:centos6 64bit. 尽 ...

  3. Android 项目中文件夹的说明与作用(转)

    (转自:http://blog.csdn.net/goodshot/article/details/11529731) Android 项目中文件夹的作用 1. src:存放所有的*.java源程序. ...

  4. stm32 USART rs485 rs232

    转载自:http://www.cnblogs.com/chineseboy/archive/2013/03/06/2947173.html 前题: 前段时间,在公司调试了一个项目,很简单,但对于初学的 ...

  5. Tomcat免安装配置2

    Tomcat 是一款优秀的JSP/Servlet容器,最初由SUN开发,后来被贡献给了Apache社区.Tomcat现在的版本已到6.Tomcat6实现了Servlet2.5和JSP2.1规范.针对w ...

  6. arc如何破循环或交叉引用

    IOS两种常见的循环引用: 1,两个类之间互相定义对方的引用 如下: //ARC code @interface A : NSObject @property (nonatomic,strong) B ...

  7. save()、saveOrUpdate()、merge()的区别

    一.Save() save()方法能够保存实体到数据库.假如两个实体之间有关系(例如employee表和address表有一对一关系),如果在没有事务的情况下调用这个方法保存employee这个实体, ...

  8. 深入Java核心 Java内存分配原理精讲

    深入Java核心 Java内存分配原理精讲 栈.堆.常量池虽同属Java内存分配时操作的区域,但其适用范围和功用却大不相同.本文将深入Java核心,详细讲解Java内存分配方面的知识. Java内存分 ...

  9. 如何查看文件是dos格式还是unix格式的?

    一.背景 由于windows和linux对换行的标识不一样,不同系统的代码传递导致代码格式的改变中可能会带来程序无法正常编译通过的问题.因此根据一些编译的错误提示,可以定位到是文件格式的问题,要对程序 ...

  10. QFontMetrics的一个问题

    今天发现QFontMetric的一个问题 QFontMetrics可以输入一个字体和一个字符串,计算出字符串在这种字体下的显示尺寸. 这种计算比较耗时间,因此Qt内部应该是缓存了计算结果.具体方法是在 ...