本次笔记内容:
03.整数的计算机表示与运算

文章目录

  • 预备知识
  • 数制
    • 数的机器表示
    • 机器字在内存中的组织
    • 字节序(Byte Ordering)
  • 整数表示
    • 计算机中整数的二进制编码方式
    • 无符号数与带符号数
      • 范围
      • 转换
      • C语言中的无符号数和带符号数
      • 何时采用无符号数
      • 加法
      • 无符号整数除以2的k次幂
      • 带符号整数除以2的k次幂
  • Integer C Puzzles
    • x<0 infer ((x*2)<0)
    • ux>=0
    • x & 7 == 7 infer (x<<30)<0
    • ux > -1
    • x > y infer -x < -y
    • x * x >= 0
    • x > 0 && y > 0 infer x + y > 0
    • x >= 0 infer -x <= 0
    • x <= 0 infer -x >= 0
    • (x|-x)>>31 == -1
    • ux>>3 == ux/8
    • x >> 3 == x/8
    • x & (x-1) != 0
  • 另一道练习题

预备知识

  • 1K = 2^10 = 1024 (Kilo)
  • 1M = 1024K =2^20 (Mega)
  • 1G = 1024M = 2^30 (Giga)
  • 1T = 1024G = 2^40 (Tera)
  • 1P = 1024T = 2^50 (Peta)
  • 1个二进制位:bit (比特)
  • 8个二进制位:Byte (字节) 1 Byte = 8 bit

注意在存储领域,不是以1024进位的,是以1000进位的。

在x86中,默认一个Word为16个比特:

  • 2个字节:Word (字)
  • 1 Word = 2 Byte = 16 bit

数制

数的机器表示

机器字(machine word)长:

  • 一般指计算机进行一次整数运算所能处理的二进制数据的位数;
  • 通常也包括数据地址长度。
  • 32位长:
    • 地址的表示空间是4GB;
    • 对很多内存需求量大的应用而言,非常有限。
  • 64位字长:
    • 地址的表示空间的是1.8 × 10^19 bytes;
    • 目前的x86-64机型实际支持48位宽的地址:256 TB。

机器字在内存中的组织

地址按照字节(byte)来定位:

  • 机器字中第一个字节的地址;
  • 相邻机器字的地址相差4(32-bit)或者8(64-bit)。

字节序(Byte Ordering)

一个机器字内的各个字节如何排序?

  • 很不幸,历史上没有过强制一统的标准,有从高位开始的,也有从地位开始的。

Big Endian:Sun,PowerPC,Internet

  • 低位字节(Least significant byte, LSB)占据高地址;

Little Endian:x86

  • 与LSB相反

例子如下。

0x100 0x101 0x102 0x103
01 23 45 67
67 45 23 01

如上,要存储数值为0x01234567的数,上面是LSB,下面是x86的存储方式。

socket就有将本地字节序与网络字节序的功能。

再举一个例子:

Decimal: 15213
Binary: 0011 1011 0110 1101
Hex: 3 B 6 D

对于以下三种实现:

int A = 15321;
int B = -15213;
long int C = 15213;

在IA32, x86-64, Sun设备上的存储分别为:

整数表示

C语言中基本数据类型的大小(in Bytes):

C Data Type Typical 32-bit x86-32 x86-64
char 1 1 1
short 2 2 2
int 4 4 4
long 4 4 8
long long 8 8 8
float 4 4 4
double 8 8 8
long double 8 10/12 10/16
char * or any other pointer 4 4 8

计算机中整数的二进制编码方式

w表示字长,对于无符号数:B2U(X)=∑i=0w−1xi⋅2iB2U(X) = \sum^{w-1}_{i=0} x_i \cdot 2^iB2U(X)=i=0∑w−1​xi​⋅2i

对于带符号数(补码,Two’s Complement):B2T=−xw−1⋅2w−1+∑i=0w−2xi⋅2iB2T = -x_{w-1} \cdot 2^{w-1} + \sum^{w-2}_{i=0} x_i \cdot 2^iB2T=−xw−1​⋅2w−1+i=0∑w−2​xi​⋅2i

对于下列实现:

short int x = 15213;
short int y = -15213;

其存储为:

Decimal Hex Binary
x 15213 3B 6D 00111011 01101101
y -15213 C4 93 11000100 10010011

对于负数(补码),即取反再加一。

符号位(sign bit):

  • 对于补码表示,MSB(Most Significant Bit)表示整数的符号;
  • 0 for nonnegative;
  • 1 for negative。

无符号数与带符号数

范围

在带符号数中,负数范围个数总比整数范围个数多1,举例:

  • 00000000表示0;
  • 00000001表示1;
  • 01111111表示127;
  • 10000001表示-127(按位取反再加1)。
  • 10000000表示-128(不能用按位取反表示,因为不存在正128,可以理解为-127-1)
转换

无符号数与带符号数之间的转换:

  • 二进制串的表示是不变的。

上图为无符号数和带符号数的关系。

C语言中的无符号数和带符号数

常数(Constants):

  • 默认是带符号数,如果有U作为后缀则是无符号数,如0U,4294967259U;

如果无符号数与带符号数混合使用,则带符号数默认转换为无符号数,包括比操作符。

下面是例题,比较常数1和常数2的关系:

Constant_1 Constant_2 Relation Evaluation
0 0U == unsigned
-1 0 < signed
-1 0U > unsigned
2147483647 -2147483647-1 > signed
2147483647U -2147483647-1 < unsigned
-1 -2 > signed
(unsigned) -1 -2 > unsigned
2147483647 2147483648U < unsigned
2147483647 (int) 2147483648 > signed

将负的带符号数转换为无符号数时,总比正的带符号数大,可以参考上面的映射示意图。

何时采用无符号数

建议:不能仅仅因为取值范围是非负而使用。只在两种情况使用:

  • 模运算
  • 按位运算

不能乱用unsigned的例子:

// example I
unsigned i;
for (i = cnt - 2; i >= 0; i--)a[i] += a[i+1];
// 永远无法结束,i恒大于等于0
// example II
#define DELTA sizeof(int)
int i;
for (i = CNT; i-DELTA >= 0; i-= DELTA)...
// sizeof()返回unsigned,而i-=DELTA运算后,i被转换为unsigned,导致for无法退出
加法

无符号数和带符号数(补码)加法所用的x86机器指令都是同一条类型。加法就是两个位串加起来。

无符号整数除以2的k次幂

在编译时,如果遇到无符号整数除以2的k次幂,不调用除法指令(硬件的除法非常慢),而调用逻辑右移。

u >> k gives ⌊u/2k⌋\lfloor u / 2^k \rfloor⌊u/2k⌋

// C Function
unsigned udiv8(unsigned x)
{return x / 8;
}
// Compiled Arithmetic Operations
shrl    $3, %eax
// Explanation
# Logical shift
return x >> 3;
带符号整数除以2的k次幂

u >> k gives ⌊u/2k⌋\lfloor u / 2^k \rfloor⌊u/2k⌋

但是如果x<0x < 0x<0,出现舍入错误。

解决方案:

  • Want ⌈x/2k⌉\lceil x / 2^k \rceil⌈x/2k⌉(需要向0舍入,而不是向下舍入)
  • (对于负数而言)Compute as ⌊(x+2k−1)/2k\lfloor (x + 2^k -1) / 2^k⌊(x+2k−1)/2k
  • In C: (x + (1<<k) - 1) >> k (即做一个偏移处理)
  • Biases dividend toward 0
// C Function
int idiv8(int x)
{return x / 8;
}
// Compiled Arithmetic Operationstestl  %eax, %eaxjs        L4
L3:sarl $3, %eaxret
L4:addl $7, %eaxjmp     L3
// Explanation
# Logical shift
if x < 0x += 7;
# Arithmetic shift
return x>>3;

Integer C Puzzles

int x = foo();
int y = bar();
unsigned ux = x;
unsigned uy = y;

x<0 infer ((x*2)<0)

不对,可能溢出。

ux>=0

对。

x & 7 == 7 infer (x<<30)<0

对。

7即111,x & 7 == 111,即x低位的3位为111。

x是int类型(32位),111向左移30位,则符号位为1,是负数。

ux > -1

不对,ux一定是小于等于-1的(-1转换为unsigned后,大)。

x > y infer -x < -y

不对,因为不一定。负数的表示范围比正数大1,若y为-128,推论将不成立。

x * x >= 0

不对,可能溢出,高位被截断。

x > 0 && y > 0 infer x + y > 0

不对,可能溢出。

x >= 0 infer -x <= 0

对。

x <= 0 infer -x >= 0

不对,-128为反例。

(x|-x)>>31 == -1

不对,0位反例。

ux>>3 == ux/8

对。

x >> 3 == x/8

不对,负数为反例。

x & (x-1) != 0

不对,x取0为反例。

另一道练习题

已知某32位整数X,其值为-101,则其16进制补码为(0xFFFFFF9B),另一32位整数Y的补码为0xFFFFFF6A,则X+Y的16进制补码(32位)为(0xFFFFFF05),X-Y的16进制补码为(0x31)。

解:

  • -101,写出其绝对值(101)2进制串,按位取反,加1;
  • 对于第二、三个空,转为10进制运算,按位取反加一即可。

【汇编语言与计算机系统结构笔记02】整数的计算机表示与运算,C中的无符号字符(unsigned)和带符号字符(signed),补码,一些例题相关推荐

  1. 【汇编语言与计算机系统结构笔记04】80x86计算机组织、保护模式、存储器、寄存器、计算机系统结构金字塔

    本次笔记内容: 05.80x86计算机组织 文章目录 计算机系统 存储器 / 主存(main memory) 80x86处理器与保护模式 历史 8086 / 8088 微处理器 80186和80286 ...

  2. 【汇编语言与计算机系统结构笔记01】x86/MIPS/ARM指令集概述与特性,一篇HPCA引发的思考(商业生态的决定性作用)

    资源Bilibili AV46914471 + AV57921488 汇编语言与计算机系统结构 清华大学 张悠慧 本次笔记内容: 01.汇编语言与计算机系统结构 02.汇编基础知识--指令集综述 文章 ...

  3. 【计算机组成原理】计算机系统结构笔记:合集

    200803本篇是郑纬民<计算机系统结构>的读书笔记,欢迎各位路过指正!今天把九章全部更新完毕啦. 0. 分章节目录 [计算机组成原理]计算机系统结构笔记(1):基本概念 [计算机组成原理 ...

  4. 计算机系统论文摘要,计算机系统结构论文摘要怎么写 计算机系统结构论文摘要范文参考...

    [100篇]免费关于计算机系统结构论文摘要范文,均为免费优秀摘要,可做为计算机系统结构相关摘要参考,是计算机系统结构相关毕业论文写作必备的免费摘要论文范本格式模板,[快快阅读吧!] 第一篇论文摘要:* ...

  5. 计算机系统结构自考大纲,自考《计算机系统结构》课程大纲说明.doc

    (一)课程内容 1.计算机系统的多级层次结构 2.计算机系统结构.组成和实现 3.软硬件的取舍与计算机系统的设计思路 4.系统结构设计要考虑解决软件的可移植性 5.应用与器件的发展对系统结构的影响 6 ...

  6. 【汇编语言与计算机系统结构笔记05】汇编的系统结构,从C代码生产汇编代码,一个具体的、经典的数据传送指令(mov)实例与分析

    本次笔记内容: 06.寻址模式与数据传输指令等 文章目录 汇编程序员眼中的系统结构 如何从C代码生产汇编代码 如何装gcc? 汇编语言数据格式 第一条汇编指令实例 数据传送指令(mov) 语法与操作数 ...

  7. 【汇编语言与计算机系统结构笔记03】浮点数的计算机表示,IEEE 754,舍入(rounding),C语言中的浮点数

    本次笔记内容: 04.浮点数的计算机表示 文章目录 IEEE的浮点数标准 IEEE的754标准 浮点数示例 计算机中浮点数二进制表示 浮点数的类型 规格化浮点数(Normalized) 规格化浮点数示 ...

  8. 【汇编语言与计算机系统结构笔记16】子程序设计:子程序的嵌套与递归,多个模块之间的参数传送

    本次笔记内容: 23.子程序设计-2-1 24.子程序设计-2-2 注:我找到了对应内容的课件,请见我于GitHub的CS笔记仓库.因此,为了节省时间,我只记录老师上课强调的内容与对应ppt页码. 本 ...

  9. 【汇编语言与计算机系统结构笔记14】循环和分支程序设计

    本次笔记内容: 18.循环程序设计-1 19.分支程序设计 注:我找到了对应内容的课件,请见我于GitHub的CS笔记仓库.因此,为了节省时间,我只记录老师上课强调的内容与对应ppt页码. 本节课对应 ...

最新文章

  1. 开放式神经网络交换-ONNX(下)
  2. 教你辨别36k纯数据科学家
  3. oracle账户锁定解决方法
  4. golang web 静态文件
  5. java编写一个函数_请教如何用java编写一个函数图像生成的应用程序?谢谢!
  6. C++实现tree树(附完整源码)
  7. c语言二分法查找一个数_算法简解-二分查找
  8. iBATIS In Action:使用映射语句(二)
  9. ThinkPHP中的find和select的区别
  10. 2019年最流行的七大编程语言:学习编程,你会选择哪一种语言呢?
  11. 基于mono和C#运行的cms产品
  12. 五月两场!! NVIDIA DLI 深度学习入门课程——计算机视觉
  13. 五百兆电信宽带玩穿越火线,电信区,延时卡70到80怎么回事,换的千兆猫和路由器,线都是六类?
  14. Ubuntu 18.04环境下Django的安装配置图文详解
  15. H3C ospf与nat转换
  16. atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc 艾提拉总结 attilax总结 1.1. 修改此java文件,让他启动编译,还是不能生成了新的class, 1 1.2. 查
  17. 数据结构——顺序表 SqList *L 和 SqList * L的区别
  18. wifi分析仪怎么看哪个信道好_wifi分析仪如何检测周围wifi信号 wifi分析仪使用方法【详解】...
  19. 40岁开始学习Android开发的我成了一名技术主管
  20. 算法入门模拟-剪刀石头布

热门文章

  1. sqlserver数据导入hdfs和hive的解决方案
  2. 基于Ubuntu16.04的GeForce GTX 1080驱动安装,遇到的问题及对应的解决方法
  3. 关于EXP-00056: 遇到 ORACLE 错误 1455 ORA-01455: 转换列溢出整数数据类型 EXP-00000: 导出终止失败 的问题解决方法整理
  4. “fatal error C1010”错误解决的三种方法
  5. 在UITableView中使用自动布局以获取动态单元格布局和可变的行高
  6. 我可以在不提供FTP访问的情况下安装/更新WordPress插件吗?
  7. maven install 安装项目问题总结An unknown compilation problem occurred
  8. activiti启动流程实例,添加进businessKey
  9. 硬盘分区表知识—详解硬盘MBR
  10. 在html中标记bdo,HTML_HTML非常用标签 optgroup、sub、sup和bdo示例代码,optgroup 用在select 标记中 可以 - phpStudy...