《深入理解计算机系统》学习笔记 - 第三课 - 位,字节和整型

Lecture 03 Bits,Bytes, and Integer count 位,字节,整型

文章目录

  • Lecture 03 Bits,Bytes, and Integer count 位,字节,整型
    • 运算:加,减,乘,除
      • 加法
      • 乘法
        • 取值范围
        • 乘法结果
    • 使用无符号注意事项
    • 内存中的表现形式
      • 面向字节的内存组织形式
      • 字长 Words
    • 字节顺序
      • 大端序和小端序
      • 代码检验数据的表现形式
    • 字符串表示
    • 拓展
      • 二进制的一个属性
      • 汇编编码
        • 乘积编码
        • 除法编码
          • 无符号除法编码
          • 有符号除法编码
      • 读字节倒转清单
    • 问题
      • 为什么十进制使用普遍?
      • 为什么用最高位作为符号位?
    • 《深入理解计算机系统》书籍学习笔记

运算:加,减,乘,除

主要运算导致溢出的情况。
都是截去超出w位的高位值。

加法

  • 无符号加法
    操作两个w位相加,结果w+1位。
    u + v = (u + v) mod 2^w

  • 有符号加法
    操作两个w位相加,结果w+1位。
    溢出的部分截去。
    在这里插入图片描述

乘法

取值范围

w 位的数的乘法结果的范围:
最高2w 位。

  • 无符号
    范围:0 <= x * y <= (2^w - 1)^2 = 2^(2w) - 2^(w+1) + 1

  • 二进制补码
    范围:
    最小值: xy >= (-2^(w-1)) * (2^(w-1) -1) = -2^(2s-2) + 2^(w-1)
    最大值(TMin)^2:x
    y <= (-2(w-1))2 = 2^(2w-2)

乘法结果
  • 无符号位
    截去高序w位的值,也就是结果模2^w。
UMult(u,v) = u * v  mod 2^w
  • 有符号位
    截去高序w位的值。

  • 2的幂的乘积与位移的关系
    左移几位就是乘以2的几次幂。

u << k = u * 2^k
  • 无符号除法与位移关系
    右移几位,就是除以2的几次幂
u >> k = u / 2^k

使用无符号注意事项

无符号数绝对不会出现负值的情况。

#include <stdio.h>
#include <unistd.h>

void main() {
    unsigned i;
    int cnt = 5;
    for (i = cnt - 2; i >= 0; i--) {
	usleep(100000);
	printf("%d,%u\n", i,i);
    }
}

// output:
// 3,3
// 2,2
// 1,1
// 0,0
// -1,4294967295
// -2,4294967294
// -3,4294967293
// ....

程序将陷入死循环。
因为无符号永远大于0.

#include <stdio.h>
#include <unistd.h>

void main() {
    #define DELTA sizeof(int)
    int i;
    int cnt = 10;
    for (i = cnt; i-DELTA >= 0; i-= DELTA) {
        usleep(100000);
        printf("%d\n",i);
    }
}

// output:
// 10
// 6
// 2
// -2
// -6
// -10
// ...

解决无符号循环问题:
使用总数作为终止判断条件,而不是0.

void main() {
    unsigned i;
    int cnt = 5;
    for (i = cnt-2; i < cnt; i--) {
        printf("%d\n",i);
    }
}

内存中的表现形式

面向字节的内存组织形式

  • 程序通过地址指向数据
    从概念上讲,可以把它想象成一个非常大的字节数组。当然实际并非如此。
  • 地址就像数组的索引
    指针变量存储地址。

注意:系统给每个进程分配私有的地址空间。

字长 Words

面向字节内存组织方式
在这里插入图片描述

32位的四个字节,64位的八个字节。

字节顺序

大端序:最低有效位字节具有最高地址
小端序:最低有效位字节具有最低地址

4字节的值:0x01234567
A

大端序和小端序

现在几乎都是小端序。

大端序:人类更容易识别。
但是对于机器来说,无所谓,只要有统一标准就行。

代码检验数据的表现形式

指向unsigned char *的指针允许作为字节数组处理

#include <stdio.h>

typedef unsigned char *pointer;

void show_bytes(pointer start, size_t len) {
    size_t i;
    for (i = 0; i < len; i++)
        printf("%p\t0x%.2x\n", start+i, start[i]);
    printf("\n");
}

void main() {
    int a= 15213;
    printf("int a = 15213;\n");
    show_bytes((pointer) &a, sizeof(int));
}

// output:
// int a = 15213;
// 0x7ffc2881f59c  0x6d
// 0x7ffc2881f59d  0x3b
// 0x7ffc2881f59e  0x00
// 0x7ffc2881f59f  0x00

字符串表示

  • 用字符数组表示。
  • 每个字符使用ASCII格式编码
    • 字符集的标准7位编码
    • 字符0 使用 0x30 编码
      数字i 使用 ox30 + i 表示
  • 字符应该有空终止符
    使用字符0

char S[6] = "18213" 编码:
在这里插入图片描述

拓展

二进制的一个属性

1 + 1 + 2 + 4 + 8 + … + 2^(w-1) = 2^w
得出:
在这里插入图片描述

汇编编码

乘积编码
  • 乘积代码
    文件mul12.c:
long mul12(long x)
{
    return x*12;
}
  • 汇编代码
    生成汇编代码: gcc -O2 -S mul12.c
    汇编文件mul12.s:
leaq (%rax, %rax, 2), %rax   // t <- x + x*2
sqlq $2, %rax                // return t << 2;
除法编码
无符号除法编码
  • 除法代码
unsigned long udiv8(unsigned long x) {
    return x/8;
}
  • 汇编代码
    生成汇编代码: gcc -O2 -S udiv8.c
    汇编文件udiv8.s:
shrq $3, $rax    // return x >> 3;
有符号除法编码

与无符号类似,不过结果需要加1。

  • 除法代码
long udiv8(unsigned long x) {
    return x/8;
}
  • 汇编代码
    生成汇编代码: gcc -O2 -S udiv8.c
    汇编文件udiv8.s:
    testq %rax, %rax // if x < 0
    js L4
L3:
    shrq $3, $rax    // x >> 3;
    ret              // ret
L4:
    addq %7, %rax    // x += 7
    jmp L3

读字节倒转清单

按小端序读取:
在这里插入图片描述

问题

为什么十进制使用普遍?

因为人们有十个手指头。

为什么用最高位作为符号位?

我们看下二进制转化为有符号数公式:
在这里插入图片描述

满足了符号数以下特征:
整数负数各一半。

再问为什么不直接用符号位来表示正负数?
下面这种表示方式:

1001
= -1*(2^0) = -1

不利于无符号有符号的转换。

当然,主要这种情况可以满足所有情况了,我们没有必要再考虑去推翻它,这个没有必然的合理优势的话是不可能推翻的。

《深入理解计算机系统》书籍学习笔记

《深入理解计算机系统》学习笔记 - 第一课 - 课程简介
《深入理解计算机系统》学习笔记 - 第二课 - 位,字节和整型
《深入理解计算机系统》学习笔记 - 第三课 - 位,字节和整型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/199749.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

交流负载的功能实现原理

交流负载的功能实现原理主要涉及到电力电子技术、电机控制技术和电力系统保护技术等多个方面。 交流负载的功能实现需要通过电力电子器件进行电能的转换和控制&#xff0c;电力电子器件主要包括开关器件和电力电子变压器等。开关器件主要用于实现电能的通断控制&#xff0c;如晶…

消息队列进阶-1.消息队列的应用场景与选型

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…

vue el-table表格中每行上传文件(上传简历)操作

1、HTML中 <el-table :data"formInfo.userListDto" border stripe max-height"400"><el-table-column type"index" label"序号" width"50"> </el-table-column><el-table-column prop"realName&q…

【Udemy】AWS CLF - 01 题库 (英文版 + 中文版)目录

【挑战业余一周拿证】CSDN官方课程目录 【挑战业余一周拿证】AWS 认证云从业者 薅200美金羊毛 一、介绍 文章记录题库&#xff08;包含答案解释中文翻译&#xff09; 共计23章&#xff0c;每天更新 2-10 章习题&#xff0c;需要的客观请点赞收藏 来源Udemy&#xff0c;刷题…

Docker容器常用命令

文章目录 启动类命令帮助类命令镜像命令列出本地主机上的镜像在远程仓库中搜索镜像下载镜像保存镜像加载 tar 包为镜像查看占据的空间删除镜像 虚悬镜像命令自动补全新建启动容器启动交互式容器启动守护式容器 列出正在运行的容器容器其他启停操作启动已经停止的容器重启容器停…

【jupyter notebook中插件 nbextensions 安装失败分析与解决方法】

文章目录 问题描述分析与解决总结 问题描述 一开始在安装 notebook 中的插件 nbextensions 时根本没有注意到版本的适配问题&#xff0c;都是进行默认的安装&#xff0c;结果安装是最新版本的 notebook7.x&#xff0c;恰好 notebook7.x 版本不再适应插件 nbextensions&#xf…

智能优化算法应用:基于头脑风暴算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于头脑风暴算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于头脑风暴算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.头脑风暴算法4.实验参数设定5.算法结果6.参考…

大数据平台/大数据技术与原理-实验报告--部署ZooKeeper集群和实战ZooKeeper

实验名称 部署ZooKeeper集群和实战ZooKeeper 实验性质 &#xff08;必修、选修&#xff09; 必修 实验类型&#xff08;验证、设计、创新、综合&#xff09; 综合 实验课时 2 实验日期 2023.11.04-2023.11.05 实验仪器设备以及实验软硬件要求 专业实验室&#xff08…

leetcode:用栈实现队列(先进先出)

题目描述 题目链接&#xff1a;232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 题目分析 我们先把之前写的数组栈的实现代码搬过来 用栈实现队列最主要的是实现队列先进先出的特点&#xff0c;而栈的特点是后进先出&#xff0c;那么我们可以用两个栈来实现&…

flask 上传文件

from flask import Flask, request, render_template,redirect, url_for from werkzeug.utils import secure_filename import os from flask import send_from_directory # send_from_directory可以从目录加载文件app Flask(__name__)#UPLOAD_FOLDER media # 注意&#xff…

大数据——一文详解数据仓库概念(数据仓库的分层概念和维度建模详解)

1、ods是什么&#xff1f; ods层最好理解&#xff0c;基本上就是数据从源表拉过来&#xff0c;进行etl&#xff0c;比如MySQL映射到Hive&#xff0c;那么到了Hive里面就是ods层。ods全称是 Operational Data Store&#xff0c;操作数据存储——“面向主题的”&#xff0c;数据…

实战Flask+BootstrapTable最实用服务端分页查询动态表头及数据(ajax方式)

看到这篇文章的朋友们是幸运的,我用了很久才实战出如下结果,且行且珍惜,祝好! 话不多说,有图有源码 1.看图,实现服务端动态表头数据,分页,查询,排序 1.数据准备 CREATE TABLE goods (id int(11) NOT NULL AUTO_INCREMENT,name varchar(255) DEFAULT NULL COMMENT 商品名,no …

运算放大器(五):V-I 转换器

1、高侧电压至电流&#xff08;V-I&#xff09;转换器 下图显示的电路是高侧电压至电流(V-I) 转换器。可将 0 V 至 2V 的输入电压转换为 0mA 至 100mA 的输出电流 其测量转换函数如下图所示&#xff1a; 可利用该电路搭建恒流源电路&#xff0c;如下图仿真电路所示&#xff08…

Linux 调试工具:gdb

调试复习 调试可谓是 “贯穿” 了程序员的一生&#xff0c;调试的重要性&#xff0c;就不再赘述啦&#xff01;如果你还不知道什么是调试&#xff0c;可以看看 Windows 系统的 Visual Studio 是如何调试的&#xff1a;➡️ visual stuudio 使用调试技巧 下载调试软件 gdb yu…

MaskDINO环境搭建与模型测试

1、环境搭建 1、构建虚拟环境安装torch conda create -n mmdetsam python3.8 -y conda activate mmdetsampip install torch1.10.0cu102 torchvision0.11.0cu102 torchaudio0.10.0 -f https://download.pytorch.org/whl/torch_stable.html -i http://mirrors.aliyun.com/pypi…

【开题报告】基于深度学习的驾驶员危险行为检测系统

研究的目的、意义及国内外发展概况 研究的目的、意义&#xff1a;我国每年的交通事故绝对数量是一个十分巨大的数字&#xff0c;造成了巨大的死亡人数和经济损失。而造成交通事故的一个很重要原因就是驾驶员的各种危险驾驶操作行为。如果道路驾驶员的驾驶行为能够得到有效识别…

跳动的文字(文字渲染).html( 网上收集的1)

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>跳动的文字</title><style>#m1:hover {animation: shine 1s linear infinite;}keyframes shine {0% {color: #fff;}50% {color: #0000ff;}100% {color: #fff;}…

C语言错误处理之 “信号处理方式<signal.h>及signal函数等内置函数”

目录 前言 signal.h头文件 信号宏 signal函数 实例&#xff1a;在Linux环境下验证signal函数 实例&#xff1a;在Linux中演示保存signal函数的返回值 预定义的信号处理函数&#xff08;简单了解&#xff09; SIG_DFL函数 SIG_IGN函数 raise函数 实例&#xff1a;测试…

电气制图用什么软件?CAD和Eplan哪个更胜一筹?

身为电气工程师&#xff0c;每天打交道最多的可能不是自家对象&#xff0c;而是时时刻刻攥在手里的电气图。目前市面上制作电路图的软件形形色色&#xff0c;但是AutoCAD Electrical和Eplan是目前大家使用率最高的两款电气制图软件。 EPLAN是一款专业的电气设计软件&#xff0…

为什么Redis这么快?5分钟成为Redis高手

Redis简介 Redis 是 C 语言开发的一个开源高性能键值对的内存数据库&#xff0c;可以用来做数据库、缓存、消息中间件等场景&#xff0c;是一种 NoSQL&#xff08;not-only sql&#xff0c;非关系型数据库&#xff09;的数据库。 Redis特点 优秀的性能&#xff0c;数据是存储…