你要明白计算机内存只能存储二进制数据,因此人类习惯的十进制只能通过一定的格式进行转换,只要是转换,就有可能丢失精度.实际上大部分CPU对浮点数和双精度都是按国际规定格式操作的,而转换工作也是CPU内部的基础功能之一.听说过"XXCPU的浮点运算很强"这样的说法吧.其实这也就是在讲CPU对浮点数或者双精度进行解码编码以及运算的能力/效率.
给你段代码你可以自己调试玩玩可以帮助你理解,你可以修改fl的初始值查看各种浮点数
#definePAUSEsystem("pause")//这个复制到主函数外面
charc,*p1;
char*p;
floatfl=-3.1415926f;
float32*fp;
uintu,e,i;
byteb;
fp=(float32*)&fl;
cout<<"解析浮点数"<<fl<<"在内存中的16进制编码"<<endl<<endl;
p=MemMap::ToString(fl,'x',1);
cout<<"内存中字节的存储顺序:"<<endl<<p<<endl<<endl;
delete[]p;
p=MemMap::ToString(fl,'x');
cout<<"转置后的字节顺序:"<<endl<<p<<endl<<endl;
delete[]p;
p=MemMap::ToString(fl,'0');
cout<<"二进制码:"<<endl<<p<<endl<<endl;
delete[]p;
p=MemMap::BitMap((void*)&fl,0x80000000);
cout<<"符号的位图(1代表负数,0代表正数):"<<endl<<p<<endl<<endl;
delete[]p;
p=MemMap::BitMap((void*)&fl,0x7f800000);
cout<<"阶码的位图:"<<endl<<p<<endl;
delete[]p;
e=fp->exp-127;
cout<<"提取阶码其值为:"<<fp->exp<<",译码后为:"<<fp->exp-127<<",意思为小数点向右移"<<e<<"位。"<<endl<<endl;
p=MemMap::BitMap((void*)&fl,0x007fffff);
cout<<"尾数的位图:"<<endl<<p<<endl;
delete[]p;
u=fp->m|0x00800000;//补上二进制尾数的最高位
p=MemMap::ToString((void*)&u,4,'b');
cout<<"编码时整数的1是省略的,因此补上1,也即小数点在尾数之前:"<<endl<<p<<endl;
delete[]p;
i=u>>(23-e);
cout<<"根据阶码向右移动小数点并取出整数部分:"<<i<<endl;
i=0xffffffff;
i=i>>(32-23+e);
i=i&u;
cout<<"小数部分转十进制为:"<<abs(fl)-3<<endl;
PAUSE;
下面是运行结果:
B. C语言实型(浮点型)数据在内存中的存放形式
实数分为float型和double型,它们分别对应IEEE 754标准中的单精度浮点数和双精度浮点数类型,在内存中的存储形式遵守IEEE 754浮点数标准。以float类型数据为例,3.14159表示成二进制为11.0010010000111111001111......,规格化后表示为1.10010010000111111001111×2^1(小数点后保留23位有效数字,因为IEEE 754标准规定的尾数为23位);指数为1,故阶码为1+127=128=10000000;这是一个正数故符号位为0,因此它在内存中的表示形式是0 10000000 10010010000111111001111,写成16进制为40490FCF。
C. C语言的基本类型在内存中怎么储存的
C语言的基本类型在内存中以二进制的形式储存的。
1、整型数据:所有整数(正负零)在内存中都是以补码的形式存在。对于一个正整数来说,它的补码就是它的原码本身。对于一个负整数来说,它的补码为原码取反再加1。
2、字符型数据:把字符的相对应的ASCII码放到存储码单元中,而这些ASCII代码值在计算机中同样以二进制补码的形式存放的。
3、实型数据:也叫浮点数,在计算机中也是以二进制的方式存储,关键在于如何将十进制的小数转化为二进制来表示。
扩展资料:
根据计算机的内部字长和编译器的版本,C语言的基本类型表示的数的长度范围是有限定的。十进制无符号整常数的范围为0~65535,有符号数为-32768~+32767。八进制无符号数的表示范围为0~0177777。十六进制无符号数的表示范围为0X0~0XFFFF或0x0~0xFFFF。
如果使用的数超过了上述范围,就必须用长整型数来表示。长整型数是用后缀“L”或“l”来表示的。长整数158L和基本整常数158在数值上并无区别。
D. C语言浮点数的储存方式为何浮点数储存不准确那个图片是什么意思
C语言中,无论是单精度还是双精度在存储中都分为三个部分:
1. 符号位(Sign) : 0代表正,1代表为负
2. 指数位(Exponent)(注:也叫阶码):用于存储科学计数法中的指数数据,并且采用移位存储(注:移码编码表示)
3. 尾数部分(Mantissa):尾数部分
关于不精确是由于十进制小数部分化二进制,常常化不尽。如同无限循环小数,最后有截断误差。
图片中的是float型的变量的存储上的格式。
E. c语言中浮点型数据的存储方式
所谓浮点数, 其实就是二进制的科学计数法. 十进制的科学计数法为 a.b * 10^n (这里 "^" 表示幂). 其中a 大于或等于1而小于10. 只有0不能用这个形式表示.
二进制的科学计数法为 1.x *10^N, 整数部分恒为1, 所以只要存贮X与N就可以.一般都是用一个位存贮符号, 再用几个二进制位存贮X, 另几个二进制位存贮N. 原则就是这样了, 但具体的格式又有所区别. 比如按IEEE来说, 有单精度, 双精度等; 还有一些软件自己定义的格式, 空间哪些位存贮X, 哪些位存贮N, 0怎么办, NaN怎么表示, 等等都要自己规定.
F. 浮点数在内存中如何存放,通过VC6。0如何观察每一位的值
浮点数保存的字节格式如下:
地址 +0 +1 +2 +3
内容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
这里
S 代表符号位,1是负,0是正
E 偏移127的幂,二进制阶码=(EEEEEEEE)-127。
M 24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现了
较高的有效位数,提高了精度。
零是一个特定值,幂是0 尾数也是0。
G. 关于c语言中浮点数在内存中的存储形式的疑惑
你这个问题非常有意义。
虽然我们都知道浮点数的格式定义在IEEE 754,我们可以换算出你定义的值。但是你这里打印的却不是我们换算出来的值,说明这样打印的方法有问题。
可以做以下试验证明:比如你定义3个一样的浮点数,float a, b ,c; a = b = c = 9.0;
理论上编码方式一样,打印出来就应该一样(无论值是什么)。可是用你的方法打印出来的结果是不一样的!!!哈哈!
具体原因我也不清楚,一直想在内存里面实际看看,最近工作忙,一直没有对比过。我怀疑是地址选择有些问题。也许用 printf("%x %x %x\n", *((unsigned int *) &a), *((unsigned int *) &b), *((unsigned int *) &c)); 打印可以解决问题。你可以试试看。或者用调试工具吊起来实际看看。
H. C语言中的float存储问题,请尽量详细解答,谢谢
float存储方式是由ieee来规定的
存储分为三个部分:
符号位(sign)
:
0代表正,1代表为负
---------1位
指数位(exponent):用于存储科学计数法中的指数数据,并且采用移位存储
--------8位
尾数部分(mantissa):尾数部分
----------23位
ieee规定:
指数偏移值是指浮点数表示法中的指数域的编码值为指数的实际值加上某个固定的值,该固定值为
2e-1
-
1,其中的e为存储指数的位元的长度。
以单精度浮点数为例,它的指数域是8个位元,固定偏移值是2^(8-1)
-
1
=
128−1
=
127.
单精度浮点数的指数部分实际取值是从128到-127。例如指数实际值为1710,在单精度浮点数中的指数域编码值为144,
即144
=
17
+
127.
科学计数法的表示为1.xxx*(2^n),尾数部分就可以表示为xxx,第一位都是1,干嘛还要表示呀?可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了24bit。而十进制里面每一位是用二进制的4位来表示的,所以24bit的精确度就是24/4
=
6
:)
一个规格化的单精度浮点数x的真值为x=((-1)^s)*(1.m)*(2^(e-127))
对于计算机中32bit表示的浮点数,表示的术的绝对值的范围约为(1e-38)~(1e+38),即2^(-127)~1.11111111b*(2^128),浮点数的绝对值再怎么小,也不可能小过2^(-127),浮点数中不存在绝对0,所以我们只能取近似值
对于第四问来说,因为在进行浮点数操作时会有四舍五入的操作
举个例子
如果a+b最后大于5则最后一位+1,然后再加上c最后结果还大于5再+1
这样一共加了两次
但是a+c可能最后小于5,然后再加上b才大于5
这样一共只加了一次
所以。。。