C语言

您所在的位置:网站首页 ieee32位浮点格式 C语言

C语言

2023-05-27 05:29| 来源: 网络整理| 查看: 265

一.整型在内存中的存储 1.原码、反码、补码

           计算机中的整数在内存中有三种表示方法:原码、反码、补码。都以二进制补码形式存在,对于有符号数据类型而言最高位为符号位,其他位为数值位;无符号数据类型全为数值位。

例如:int i=5; 4字节=32位 二进制形式:0 000 0000 0000 0000 0000 0000 0000 0101 符号位 数值位 //符号位:0代表正,1代表负

           正数的原码、反码、补码相同;负数则以补码的形式存储。

           原码:直接将整数转换成二进制的形式即可。

           反码:原码的符号位不变,数值位按位取反。

           补码:反码+1。

例如:int i=-1; 负数以补码的形式存在,如何转换呢?如下: 第一步:原码:1000 0000 0000 0000 0000 0000 0000 0001 第二步:反码:1111 1111 1111 1111 1111 1111 1111 1110 第三步:补码:1111 1111 1111 1111 1111 1111 1111 1111 2.大小端存储模式

         定义:内存中的字节排序

         大端存储模式:数据的低位存在内存的高地址中

         小端存储模式:数据的低位存在内存的低地址中

 

          这里内存中的地址从左向右,由上往下依次增高,显示的是16进制数据,i的地址是0x00043FE58 ,那14 00 00 00 是怎么回事呢?

int i =20; //0000 0000 0000 0000 0000 0000 0001 0100 //00 00 00 14 二进制数据转换成十六进制后低位是14存在了低地址中(小端存储) 大端存储显示:0x00043FE58:00 00 00 14 3.整型提升

         先看另一篇https://mp.csdn.net/mp_blog/creation/editor/130477318

   思考3.1

#include int main() { char a = -1; //1111 1111 1111 1111 1111 1111 1111 1111 -1的整数补码 //1111 1111 由于是char类型存储,只取低8位的数 signed char b = -1; //同上 unsigned char c = -1; //同上 printf("a=%d,b=%d,c=%d",a,b,c);//这里以有符号十进制的形式输出打印,发生了整型提升 //a:1111 1111 1111 1111 1111 1111 1111 1111 最高位则要视为符号数,由于是负数,需转换成原码输出 //a的原码:1000 0000 0000 0000 0000 0000 0000 0001 显示结果:a=-1; //b:1111 1111 1111 1111 1111 1111 1111 1111 //b的原码:1000 0000 0000 0000 0000 0000 0000 0001 显示结果:b=-1; //c:0000 0000 0000 0000 0000 0000 1111 1111 符号位是0代表是正数,正数的原反补相同,直接输出 //c的显示结果:c=255 return 0; }

思考3.2

#include int main() { char a = -128; //1000 0000 0000 0000 0000 0000 1000 0000 -128原码 //1111 1111 1111 1111 1111 1111 0111 1111 反码 //1111 1111 1111 1111 1111 1111 1000 0000 补码 //1000 0000 截取 printf("%u\n",a); //1111 1111 1111 1111 1111 1111 1000 0000 整型提升 //由于%u是以无符号十进制形式输出,因此最高位视为数值位,直接输出 //4294967168 return 0; }

思考3.3

#include int main() { char a = 128; //0000 0000 0000 0000 0000 0000 1000 0000 //1000 0000 截取 printf("%u\n",a); //1111 1111 1111 1111 1111 1111 1000 0000 整型提升 //4294967168 return 0; }

 或者127+1得到-128,同思考3.2的原理,此处涉及数据类型范围的知识,自行百度了解。

思考3.4

#include int main() { int i = -20; //1111 1111 1111 1111 1111 1111 1110 1100 -20的补码 unsigned int j = 10; //0000 0000 0000 0000 0000 0000 0000 1010 10的补码 prinf("%d\n",i+j); //1111 1111 1111 1111 1111 1111 1111 0110 i+j //由于是%d,最高位为符号位,1代表负数,需转换成原码输出打印 //1000 0000 0000 0000 0000 0000 0000 1010 显示结果:-10 return 0; }

思考3.5

#include int main() { unsigned int i; for (i = 9; i >= 0; i--) { printf("%u\n",i); //前十次显示结果:9 8 7 6 5 4 3 2 1 0 i=-1呢? //1111 1111 1111 1111 1111 1111 1111 1111 -1的补码,此处的符号位视为数值位 //1111 1111 1111 1111 1111 1111 1111 1110 //0000 0000 0000 0000 0000 0000 0000 0001 原码,此处的i被转为了1 } return 0; } //死循环

思考3.6

#include int main() { char a[1000]; // char的数据范围:-2^7 ~ 2^7-1 -128~127 int i; for (i = 0; i < 1000; i++) { a[i] = -1 - i; //i=127时,a[i]==-128; //i=128时,a[i]==-129==127; //i=129时,a[i]==-130==126; //i=255时,a[i]==0=='\0' 字符串结束标志 //... //直到i=1001时结束循环,此时有多个'\0',但strlen函数只识别到第一个‘\0’结束 } printf("%d",strlen(a)); //255 return 0; }

思考3.7

#include int main() { unsigned char i = 0; //数据类型范围:0~2^8-1 即 0~255 for (i = 0; i 0 { printf("hello world\n"); //死循环 } return 0; } 二.浮点数在内存中的存储

3.1 一个例子 浮点数存储的例子:

int main() { int n = 9; float *pFloat = (float *)&n; printf("n的值为:%d\n",n); printf("*pFloat的值为:%f\n",*pFloat); *pFloat = 9.0; printf("num的值为:%d\n",n); printf("*pFloat的值为:%f\n",*pFloat); return 0; }

输出的结果是什么呢?

3.2 浮点数存储规则

      num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?

要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。

详细解读:

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式: 

 举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。

那么,按照上面V的格式,可以得出s=0,M=1.01,E=2。

十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。

那么,s=1,M=1.01,E=2。

IEEE 754规定: 对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M

 IEEE 754对有效数字M和指数E,还有一些特别规定。

前面说过, 1≤M



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3