C/C++中整数与浮点数在内存中的表示方式

  在C/C++中数字类型主要有整数与浮点数两种类型,在32位机器中整型占4字节,浮点数分为float,double两种类型,其中float占4字节,而double占8字节。下面来说明它们在内存中的具体表现形式:

  整型:

  整型变量占4字节,在计算机中都是用二进制表示,整型有无符号和有符号两种形式。

  无符号变量在定义时只需要在相应类型名前加上unsigned 无符号整型变量用32位的二进制数字表示,在与十进制进行转化时只需要知道计算规则即可轻松转化。需要注意的是在计算机中一般使用主机字节序,即采用“高高低低的方式”,数字高位在高地址位,低位在低地址位,例如我们有一个整数0x10203040那么它在内存中存储的格式为:04 03 02 01。

  有符号数将最高位表示为符号位,0为正数,1为负数其余位都表示具体的数值,对于负数采用的是补码的方式,补码的规则是用0x100000000减去这个数的绝对值,也可以简单的几位将这个数的绝对值取反加1,这样做是为了方便将减法转化为加法,在数学中两个互为相反数的和为0,比如现在有一个负数数x,那么这个x + |x| = 0这个x的绝对值是一个正数,但是用二级制表示的两个数相加不会等于0,而计算机对于溢出采用的是简单的将溢出位丢弃,所以令x + |x| = 0x100000000,这个最高位1,已经溢出,所以这个结果用四字节保存结果肯定会是0,所以最终得到的x = 0x100000000 - |x|。

  浮点数:

  早期的小数表示采用的固定小数点的方式,比如规定在32位二级制数字当中,哪几位表示整数部分,其余的表示小数部分,这样表示的数据范围有限,后来采用的是小数点浮动变化的表示方式,也就是所谓的浮点数。

  浮点数采用的是IEEE的表示方式,最高位表示符号位,在剩余的31位中,从左往右8位表示的是科学计数法的指数部分,其余的表示整数部分。例如我们将12.25f化为浮点数的表示方式:

  首先将它化为二进制表示1100.01,利用科学计数法可以表述为:1.10001 * 2^3

  分解出各个部分:指数部分3 + 127= 011 + 0111111、尾数数部分:10001

  需要注意的是:因为用科学计数法来表示的话,最高位肯定为1所以这个1不会被表示出来

         指数部分也有正负之分,最高位为1表示正指数,为0表示负指数,所以算出来指数部分后需要加上127进行转化。

  将这个转化为对应的32位二级制,尾数部分从31位开始填写,不足部分补0即:0 | 10000010 | 10001 |000000000000000000,隔开的位置分别为符号位、指数位,尾数位。

  因为有的浮点数没有办法完全化为二进制数,会产生一个无限值,编译器会舍弃一部分内容,也就说只能表示一个近似的数,所以在比较浮点数是否为0的时候不要用==而应该用近似表示,允许一定的误差,比如下面的代码:

float fTemp = 0.0001f
if(fFloat >= -fTemp && fFloat <= fTemp)
{
    //这个是比较fFloat为0
}

double类型的浮点数的编码方式与float相同,只是位数不同。double用11位表示指数部分,其余的表示尾数部分。

  浮点数的计算在CPU中有专门的浮点数寄存器,和对应的计算指令,在效率上比整型数据的低。

在写程序的时候,我们利用变量名来进行变量的识别,但是计算机根本不认识这些变量名,计算机中采用的是直接使用地址的方式找到对应的变量,同时为了能准确找到对应的变量,编译器会生成一个结构专门用于保存变量的标识名与对应的地址,这个标识名不是我们定义的变量名,而是在此基础上添加了一些符号,如下面的例子:

extern int nTemp;
int main()
{
    cout<<nTemp<<endl;
}

我们申明一个变量,然后在不定义它的情况下,直接使用,这个时候编译器会报错,表示找不到这个变量,报错的截图如下:

我们可以看到编译器为这个变量准备的名称并不是我们所定义的nTemp,而是添加了其他标示。

在声明变量的时候编译器会为它准备一个标示名称,在定义时会给它一个对应的内存地址,以后在访问这个标示的时候编译器直接去它对应的内存位置去寻找它,下面我们添加这个变量的定义代码:

extern int nTemp;
int nTemp = 0;
int main()
{
    cout<<nTemp<<endl;
    return 0;
}

我们查看对应的汇编代码:

11:       ;int nTemp = 0;
00401798   mov         dword ptr [ebp-4],0
12:       ;cout<<nTemp<<endl;

我们可以看到在为这个变量初始化的时候编译器是直接找到对应的地址[ebp - 4],没有出现相关的变量名,所以说我们定义的变量名只是为了程序员能够识别,而计算机是直接采用寄存器寻址的方式来取用变量。

在编译器中同时也看不到与变量类型相关的代码,编译器在使用变量是只关心它的位置,存储的值,以及如何将其中的二进制翻译为对应的内容,代码如下:

int main()
{
    int nTemp = 0x00010101;
    float *pFloat = (float*)&nTemp;
    char *pChar = (char*)&nTemp;
    cout<<nTemp<<endl;
    cout<<*pFloat<<endl;
    cout<<pChar<<endl;
    return 0;
}

结果如下:

从这可以看出同一块内存因为编译器根据类型将它翻译为不同的内容,所展现的内容不同。

时间: 2024-10-13 02:33:25

C/C++中整数与浮点数在内存中的表示方式的相关文章

浮点数在内存中的存储(简述)

数据类型: 1.基本类型(整形,浮点型,字符型) 2.构造类型(数组,结构体,联合,枚举) 3.指针类型 查看数据范围:整形范围(limits.h) 浮点型类型(flaot.h) eg:有符号的char的表示范围:0000 0000~1111 1111(-128~127)其中最高位表示符号位,0为正 1为负 其实数据的存储和访问就下像作图这个圈一样,当你给它的127+1它就会变成128 整形变量: 一般来说字长为32的情况下,整形表示32位,短整形16位,长整形32位 数据在计算机中以补码的形式

移码及浮点数在内存中的存储方式

首先说一下十进制的小数怎么转化为二进制的小数,计算机根本就不认识10进制的数据,他只认识0和1,所以,10进制的小数在计算机中是用二进制的小数表示的. 十进制的小数转化为二进制的小数的方法: 可以简单的概括为正序取整,将十进制的小数部分乘以2,然后取整数部分. 例如将0.2转化为二进制的小数,那么0.2*2=0.4,其整数部分是0,所以二进制小数的第一位为0,然后0.4*2=0.8,其整数部分是0,所以二进制小数的第二位为0,然后0.8*2=1.6,其整数部分是1,所以二进制小数的第三位是1,然

浮点数在内存中的表示

        1. 浮点数的二进制格式. 浮点数的二进制格式如下, 分为 3 个部分, 即 sign (符号位), exponent (指数位), 以及 significand (有效数位). 如下图所示: single-precision floating point(单精度浮点数), 4 字节, 共 32 位: 31            23   22                               0         +---------------------------

整型数与浮点数在内存中的表示

落下的基础还是要早点补起来的... 整型数在内存中存储 正整数 以int a = 25为例 1.      将a用2进制表示 (25)10 = (11001)2 因为int型在内存中占4个字节,也就是32位,实际是 (0000 0000 0000 0000 0000 0000 0001 1001) 2.      用16位表示 (0 0 0 0 0 0 19) à(00 00 00 19) 在内存中低地址在高位,也就是 19 00 00 00 负整数 以int b = -25为例 1.    将

Python中整数和浮点数

Python支持对整数和浮点数直接进行四则混合运算,运算规则和数学上的四则运算规则完全一致. 基本的运算: 1 + 2 + 3 # ==> 6 4 * 5 - 6 # ==> 14 7.5 / 8 + 2.1 # ==> 3.0375 使用括号可以提升优先级,这和数学运算完全一致,注意只能使用小括号,但是括号可以嵌套很多层: (1 + 2) * 3 # ==> 9 (2.2 + 3.3) / (1.5 * (9 - 0.3)) # ==> 0.4214559386973180

C语言中浮点数在内存中的存储方式

关于多字节数据类型在内存中的存储问题 //////////////////////////////////////////////////////////////// int ,short 各自是4.2字节.他们在内存中的存储方式以下举个样例说明. int data = 0xf4f3f2f1; 当中低位存放在编址小的内存单元.高位存放在编址高的内存单元 例如以下: 地址:0x8000      0x8001    0x8002   0x8003 数据:   f1              f2 

C/C++浮点数在内存中的存储方式

任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100.则在Intel CPU架构的系统中,存放方式为  10000100(低地址单元) 00000100(高地址单元),因为Intel CPU的架构是小端模式.但是对于浮点数在内存是如何存储的?目前所有的C/C++编译器都是采用IEEE所制定的标准浮点格式,即二进制科学表示法. 在二进制科学表示法中,S=M*2^N 主要由三部分构成:符号位+阶码(N)+尾数(M).对于fl

浮点数在内存中的存放方式

C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53. 无论是单精度还是双精度在存储中都分为三个部分: 符号位(Sign)

java中的各种数据类型在内存中存储的方式

1.java是如何管理内存的 java的内存管理就是对象的分配和释放问题.(其中包括两部分) 分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对象申请内存空间(基本类型除外),所有的对象都在堆(Heap)中分配空间.释放:对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作.但同时,它也加重了JVM的工作.因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请.引用.被引用.赋值等,GC都需要进行监控. 2.什么叫java的内存泄露 在j