CSAPP学习笔记——Integer Representation

TOD和PPS精确时间同步技术 授时 阅读详情

整数的二进制底层表示

对于字长(word size)为w的机器,用w位bit表示一个字(word)。

[xw−1,xw−2.....x0]

无符号整数的二进制表示

如果该字表示一个无符号整数的话,我们可以用下列公式来计算

unsinged=∑i=0w−1xi2i

范围 : 0<=x<2w−1

有符号整数的二进制表示

如果该字表示一个有符号整数的话,现代计算机通常使用补码(two’s complement)方式的编码方式。
补码的确定规则基于这样的事实:
对于一个正整数x,它的相反数y,那么x+y=0是符合我们的直觉的。
对于[xw−1,xw−2.....x0]例如x=0000001想找另外的一个[yw−1,yw−2.....y0] y使得x+y=0000000(如果bitlen(x+y)==w+1截断最高位)那么y=1111111推导出y= x+1
因为x=0000001表示正整数的1,为了使得y=1111111表示-1,我们采用以下公式 :

signed=−xw−12w−1+∑i=0w−2xi2i

我们给了最高位一个很大的负权重来达到我们的目的。
范围 : −2w−1<=x<=2w−1−1
这种编码方式成为补码。

使用 <stdints.h> 和<inttype.h>

由于不同机器的字长(字长影响数据范围)不同,c语言在不同字长的机器上int的大小可能略有区别,考虑到可移植性,我们应该尽量使用c99标准库的<stdints.h和<inttype.h>中的类型。

int main(void)
{
    int16_t  x0 = 10;
    int32_t  x1 = 10000;
    int64_t  x2 = 1000000000000;
    printf("x0 : %d\n",x0);
    printf("x1 : %d\n",x1);
    printf("x2 : %" PRId64 "\n", x2);
    return 0;
}

需要注意的是输出int64_t的时候使用PRId64这是<inttype.h>中的一个宏。

有符号整数和无符号整数之间的转换

c语言中一旦操作符某一边出现了unsigned int那么都会被自动转换为unsigned int这种转换是隐式的不宜察觉,很多bug由此出现。应当了解具体的细节。
转换的时候,bit sequence是不会改变的,只是编译器对它的解释方式发生变化。

有符号->无符号

singned−>unsigned={x+2w,x<0x,x>=0

看一个例子 :
int x = -50;//signed
unsigned y = 1;
if(x > y)
    printf("ok\n");

程序输出为ok,这是因为if(x > y)这条语句,x是signed,y是unsigned,x会自动cast为unsiged,根据上边的公式可知,cast后必定大于1,所以会输出ok

无符号->有符号

unsingned−>signed={x,x<2w−1x−2w,x>=2w−1

看一个例子 :
unsigned x = (1 << 31);
int y = x;
printf("x = %ud , y = %d\n",x,y);
x = 2147483648d , y = -2147483648

套用上述公式即可解释

整数二进制表示形式的扩展和截断

不同字节的整数转换是一种常见的操作。

无符号整数的扩展

对于w字长的无符号整数[xw−1,xw−2.....x0]假设变为w+k位,那么很简单的就是高位补k个0变为[0,0,0,0,0..xw−1,xw−2.....x0],这种方式称为zero extension.

无符号整数的截断

假设我们不扩展无符号整数,由于某种特殊需求我们要截断它,对[xw−1,xw−2.....x0]w位比特串变为[xk−1,xk−2.....x0]k位(即去掉最高的w-k位),我们将会得到x mod 2k
证明 :

[xw−1,xw−2,...x0]mod2k=[∑i=0w−1xi2i]mod2k=[∑i=0k−1xi2i]mod2k=∑i=0k−1xi2i=[xk−1,xk−2,...x0]mod2k

有符号整数的扩展

对于w字长的有符号整数[xw−1,xw−2.....x0]假设变为&w+k位,那么很简单的就是最高位重复k次(再加上原来的最高位一共有k+1个x(w−1),变为[x_{w-1},x_{w-1},x_{w-1},x_{w-1}x_{w-1},x_{w-2}…..x_{0}]$,这种方式称为sign extension.
下面我们证明 :

[xw−1,xw−2.....x0] ==[xw−1,xw−1,xw−1,xw−1xw−1,xw−2.....x0]

只需要证明:

[xw−1,xw−1,xw−2.....x0] =[xw−1,xw−2.....x0]即可

证明 :

[xw−1,xw−1,xw−2,…x0] =−xw−12w+∑w−1i=0xi2i=−xw−12w+xw−12w−1+∑w−2i=0xi2i=−xw−12w−1+∑w−2i=0xi2i=[xw−1,xw−1,xw−2,…x0]

有符号整数的截断

假设我们不扩展有符号整数,由于某种特殊需求我们要截断它,对[xw−1,xw−2.....x0]w位比特串变为[xk−1,xk−2.....x0]k位(即去掉最高的w-k位,去掉了最高w-k位那么符号位就被去掉了)
所以 :

(signed)[xw−1,xw−2,...x0]

我们采用以下公式 :
step 1 : res = x mod 2w
setp2 : res(unsigned) -> res(signed)
例如 : x=−7(1001),我们先将1001解释为unsigned得到9,截断一位即9 mod2k,k=3得到1在将unsigned(1)−>signed()仍然得到1,所以−7截断最高位后为1。
上述k表示的是截断后的比特串的长度。

整数的运算

整数的加法

无符号整数的加法

对于w字长的无符号整数[xw−1,xw−2.....x0],表示的范围为0<=x<2w−1 ,那么x+y的范围为0<=x<2w+1−2显然需要w+1位比特串来保存,所以加法会出现溢出的情况,实际上,机器内部进行了取余运算,所以 :

x+uwy={x+y,x+y<2wx+y−2w,2w<=x+y<2w+1

我们可以用下列函数判断两个数相加是否溢出 :
int unsigned_add_ok(unsigned x,unsigned y)
{
    unsigned sum = x + y;
    return (sum >= x) ? 1 : 0;
}

有符号整数的加法

x+uwy=⎧⎩⎨⎪⎪⎪⎪x+y−2w,x+y>=2w−1x+y,−2w−1<=x+y<2w−1x+y+2w,x+y<−2w−1

可以用下列函数判断两个有符号整数相加是否溢出:
int signed_add_ok(int x,int  y)
{
    int sum = x + y;
    if( x < 0 && y < 0 && sum > 0 )
        return 0;//negative overflow
    else if(x > 0 && y > 0 && sum < 0)
        return 0;//positive overflow
    return 1;
}

整数取反(减法相当于加相反数)

无符号整数

基于公式(x+2w−x) mod 2w=2w mod 2w = 0
所以无符号整数取反将得到 :

−uwx={x,x=02w−x,x>0

有符号整数

−uwx={−x,x>−2w−1−2w−1,x=−2w−1

这个略微有些特殊假如说w = 3,−2w−1表示为100那么只有再加上100才能得到0000表示0

整数乘法

无符号整数的乘法

对于w字长的无符号整数[xw−1,xw−2.....x0],表示的范围为0<=x<2w−1 ,那么x+y的范围为0<=x<22w−2w+1+1显然需要2w位比特串来保存,所以乘法会出现溢出的情况,实际上,这里机器内部仍然进行了取余运算,所以 :

x∗uwy=(x∗y)module2w

可以用以下函数检验无符号整数相乘是否溢出:
int unsigned_multiply_ok(unsigned x,unsigned  y)
{
    unsigned product = x * y;
    if(x != 0 && product / x != y)
        return 0;
    return 1;
}

有符号整数的乘法

类似有符号整数的截断运算(因为乘法很有可能会超出范围)。
我们首先将有符号整数的比特序列解释为无符号整数,然后无符号整数相乘遵循 mod 2k的法则,得到的结果再解释为有符号整数即可。
例 :
x=[101]=−3 解释为unsigned得到x=5
y=[011]=3 解释为unsigned得到y=3
所以 :
x∗y=3∗5=15(001111)mod23=7(111)解释为signed得到−1
可以用以下函数检验有符号整数相乘是否溢出

int signed_multiply_ok(int x,int  y)
{
    int product = x * y;
    if(x != 0 && product / x != y)
        return 0;
    return 1;
}//同unsigned_multiply_ok

乘以常量

乘法需要多条机器指令,比较慢。一般来讲编译器会使用左移和加减法指令来替换掉乘法指令。
这很简单 :
x∗14=x∗(8+4+2)=(x<<3)+(x<<2)+(x<<1)
或者
x∗14=x∗(16−2)=(x<<4)−(x<<1)
x∗55=(64−8−1)=(x<<6)−(x<<3)−x
诸如此类。

除以2的幂

除法操作更加耗时,不过没有很好的优化方式。当除以2k这种形式的时候,编译器会将其优化为右移操作。
对于无符号整数,采用逻辑右移。
对于有符号整数,采用算术右移。
算术右移有些特殊,对于−12340我们看一个表:

k算术右移k位Decimal/2k
01100111111001100-12340-12340.0
11110011111100110-6170-6170.0
41111110011111100-772-771.25
81111111111001111-49-48.203125

可以看出,单纯这样除是不精确的值,为了使得结果正确,使用下列公式:

x/2k={x>>k,x>=0(x+2k−1)>>k,x<0
走向审计4.0:内部审计数字化转型的路径与方法 企业的内部审计人员可以以数字化为手段,建立内部审计新生态,在数字化过程中引进战略审计、服务审计、开放审计、敏捷审计、数字审计、智慧审计等理念、方法和工具,完成数智生态审计转型。内部审计的审计对象远比国家审计和公众审计丰富和多元化,理论上企业经营管理和日常操作的各个方面都可以成为内部审计的对象,此外还可以开展独立咨询活动。由于内部审计的数字化或数字化的内部审计是实现审计数字化转型的必要条件,是实现“数字引领、数据强审”目标的核心手段,因此企业内部审计部门势必要投入足够的资金和人才来打造一支数字化审计新队伍。 阅读详情

相关推荐

【交易系统系列27】带你看懂订单的“奇幻漂流”

作为一个在交易所后台“厨房”里摸爬滚打了十多年的老兵,我将用一杯手冲咖啡的时间,带你亲历一次完整的订单“奇幻漂流”。本文将用一个“奶爸”的生活视角,硬核拆解**撮合(Matching)**、**清算(Clearing)**、**结算(Settlement)**和**出入金**这四大核心环节。这不仅是一次对**交易系统优化**和**撮合引擎架构**的深度剖析,更是一场关于传统金融与数字金融两种不同“上菜”哲学的真实故事。

weixin_43988453的博客 406

【读书笔记】语言基础-数值(四)

《Lua程序设计-第4版》读书笔记

qq_41436235的博客 3102

VJ runtime error可能的原因

runtime error (运行时错误)就是程序运行到一半,程序就崩溃了。比如说:①除以零②数组越界:int a[3]; a[10000000]=10;③指针越界:int * p; p=(int )malloc(5 sizeof(int)); *(p+1000000)=10;④使用已经释放的空间:int * p; p=(int )malloc(5 sizeof(int));free(p);

dreambyday 3万+

高通平台蓝牙学习-- 基于WCN6750 Bluetooth 5.2的讲解

摘要:蓝牙5.2解决方案WCN6750具备多项先进特性:完全兼容5.2标准及ANT+协议,支持2Mbps高速BLE和长距离传输;采用射频集成方案,与WLAN共享天线并支持5G并发;内置功率放大器,支持Class1/2传输;提供双音频流和Slimbus接口优化。其HCI UART接口支持3.2Mbps速率,通过BlueZ协议栈实现蓝牙5.2功能,包括2Mbps模式和长距离传输,符合核心规范要求。(149字)

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 3万+

【Windows Server 2019】组策略的配置与管理——理论基础

博文介绍了组策略的定义,作用和分类。组策略包括计算机配置和用户配置;组策略又分为为基于本地的组策略和基于AD(活动目录)的域组策略。并说明了不同组策略发生冲突时默认的规则。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 1万+

Lua源码学习-lauxlib.c

/* ** $Id: lauxlib.c,v 1.284 2015/11/19 19:16:22 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ #define lauxlib_c #define LUA_LIB #include "lprefix.h" #include <errno.h> #include <stdarg.h&g

Shanks 952

cesium实战目录必看

本文作者长期从事GIS相关工作,专注于三维和地图可视化领域,熟悉Cesium、Three.js、WebGL等开发框架。文章目录展示了作者在Cesium应用中的多项技术实践,涵盖水面反射、离屏渲染、后处理效果、地形裁剪、Shader着色器、动态单体化、气象图、缓冲区域、坡度和坡向分析、三维热力图、通视分析、态势标绘等多个方面。这些内容为开发者提供了丰富的技术参考,展示了Cesium在三维可视化中的强大功能和应用场景。

God's asylum的博客 8718

2.2 Integer representation

2.2.2 Unsigned Encoding Both C and C++ support signed(the default) and unsigned numbers, and Java support only signed numbers. we denote to be the entire bit vector, and devote individual bits as ...

weixin_30652879的博客 191

【AI编程】Codex 进阶与高阶技巧:从熟练到精通——2026 最新教程

Skill 是 Codex 的「插件」—— 一段 Markdown 定义触发条件、输入参数和执行流程。比自定义命令更强大,支持参数化、多步骤、条件判断。

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 192

高性能算力中心 — RDMA — Overview

目录 文章目录目录RDMA基于以太网的 RoCE/RDMA 计算优化NVMeNVMe Over Fabrics基于以太网的 NVMe 存储优化 RDMA RDMA(Remote DMA,远程直接内存访问)是一种新的内存访问技术,RDMA 让计算机可以直接存取其他计算机的内存,而不需要经过 CPU 耗时的处理。RDMA 将数据从一个系统快速移动到远程系统存储器中,而不对操作系统造成任何影响。RDMA 技术的原理及其与 TCP/IP 架构的对比如下图所示。 InfiniBand(IB):从一开始就支持 R

烟云的计算 2365

lauxlib.c(5.3.4)解析

/* ** $Id: lauxlib.c,v 1.289 2016/12/20 18:37:00 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ #define lauxlib_c #define LUA_LIB #include "lpref

活在阳光下 1514

飞牛NAS新增虚拟机功能,如果使用虚拟机网卡直通安装ikuai软路由(如何解决OVS网桥绑定失败以及打开ovs后无法访问飞牛nas等问题)

飞牛NAS新增虚拟机功能,如果使用虚拟机网卡直通安装ikuai软路由

XiaoqiangClub的博客 1万+

深入理解计算机系统 lab1 ——datalab 解答 (95个ops)

/* * CS:APP Data Lab * * * * bits.c - Source file with your solutions to the Lab. * This is the file you will hand in to your instructor. * * WARNING: Do not include the header;

KQZXCMH的博客 3万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

CSAPP-数据表示与运算实验

基于对三大类运算:位操作、补码运算和浮点数运算得操作的学习和使用,更好地熟悉和掌握了计算机中整数和浮点数的二进制编码表示,并且此次的习题加深了对数据二进制编码表示的了解。

weixin_52511526的博客 5061

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

lua math.random伪随机问题浅析

在lua中,如果我们需要随机数的时候,会使用到math.random,为了避免伪随机我们的一般编写方式如下: -- 获取当前系统时间(秒)作为随机种子 math.randomseed(os.time()) -- 有三种方式: -- 1. 不带参数调用时,获取的是[0,1)范围内的随机浮点数 -- 2. 带一个整型参数时,获取的是[1,n]范围内的随机整数 -- 3. ...

all36426的博客 2840

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Lua中的数值

文章目录数值常量算术运算关系运算数学库随机数发生器取证函数表示范围 数值常量     我们可以使用科学计数法(一个可选的十进制部分外加一个可选的十进制指数部分)书写数值常量,例如: > 4 --4 > 0.4 --0.4 > 4.57e-3 --0.00457 > 0.3e12 --3.0000000000.0 > 5E+20 --...

4114

cocos lua 个人总结

* 关于and和or,注意返回的结果不是true或false,比如: 4 and 5   -- 5 nil and 1 -- nil false and 1   -- false 0 or false   -- 0,在lua中,只有false和nil被认为“假” nil or fasle -- false false or nil -- nil...

weixin_30914981的博客 448

Integer.numberOfLeadingZeros(int i)

/** * Returns the number of zero bits preceding the highest-order * ("leftmost") one-bit in the two's complement binary representation * of the specified {@code int} value. Returns 32

wtm 5843

(转载搬运)《深入理解计算机系统/CSAPP》 Data Lab

找了很多资料,感觉这个写得最好 原文地址: https://www.jianshu.com/p/9471ec73463a 1 absVal(int x) 计算x的绝对值 4 8 2 addOK(int x,int y) 判断x+y是否溢出 3 20 3 allEvenBits(int x) 判断二进制数偶数位是否全为1 ...

weixin_42062229的博客 2万+

Number Complement问题及解法

问题描述: Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation. Note: The given integer is guaranteed to fit within the

刘天的博客 396

Integer源码详解

尊重原创,转载请标明出处    http://blog.youkuaiyun.com/abcdef314159 对于Integer这个类估计大家也都非常熟悉了,以前看过他的源码,但也只是粗略的看了一下,最近有时间认真的看了一下发现这个类设计的非常好,所以就打算记录下来与大家共享。我们看一下java项目中的Integer类大概有500多行,并且注释也很少, 而Android中的Integer大概有1000多...

数据结构和算法 3459

Lua笔记--number的存储

Lua 笔记–number的存储Lua语言里面的数字类型是number,没有像C/C++里面那样多种多样,如果是这样的话,那么在计算机内数字就应该是按照浮点数存储的,而浮点数存储不是有不确定性吗?不会出现类似1+2=2.9999999999的错误吗?这个问题在Roberto Ierusalimschy的《Programming In Lua》一书中进行了说明 Some people fear t

Focus 4425

Java(四)常用类:Number类之Integer.parseInt()

文章目录 将表示数字的String字符串转化成Integer类型。 注意:如果其中的字符不是数字,那么就会报错。 String n="123"; Integer num=Integer.parseInt(n); String m="123hello"; /! Integer errorNum=Integer.parseInt(m); ...

sandalphon4869的博客 1148

AttributeError: module ‘numpy‘ has no attribute ‘integer‘

问题的主要原因,是numpy的版本不合适,卸载以后,重新安装一下,就可以了。 安装numpy : pip uninstall numpy 卸载numpy : pip install -U numpy

尚未佩妥剑 转眼便江湖 1万+
上一篇: 基数排序
下一篇: 二分图的最大匹配——匈牙利算法
SixDayCoder
博客等级 码龄12年 98粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值