900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > c语言如何将浮点数转换为字节 浅谈C语言整型与浮点型转换

c语言如何将浮点数转换为字节 浅谈C语言整型与浮点型转换

时间:2019-04-30 04:06:54

相关推荐

c语言如何将浮点数转换为字节 浅谈C语言整型与浮点型转换

本篇博客将阐述、讨论的内容:

●int

int的范围根据计算机的不同存在16位或32位的差异,以16位举例,最大值为1111 1111 1111 1111,也就是65535,如果出现65536,就会溢出。

●unsigned int(无符号整型)

以16位系统为例,unsigned int能存储的数据范围是0~65535(需要注意整数是以补码形式存放)。其进行的是模数计算,也就是所谓的二进制相加减,计算方法和十进制加减并无区别,但是unsigned int有着正溢出和负溢出的问题。

对于正溢出与负溢出,诸多基础概念便不再赘述,不懂的朋友可以去回顾计算机组成原理的相关知识。

这里仅举出一个负溢出的例子:

进行自然丢弃后,可知结果为0。很明显,产生了负溢出。

●接下来,我们说说unsigned int和int的相互转化,代码如下:

float sum_elements(float a[],unsigend length){

float result = 0;

for(int i = 0; i <= length - 1; i++){

result += a[i];

return result;

}

}

很显然,计算一个数组所有元素之和。但当数组为空时,length输入0,会返回一个存储器错误。为什么呢?请看unsigned int的计算,length是unsigned int 类型,进行的是模数运算,只代表正数,如果出先了0000000(这里有32个0)-00000..01(31个0,1个1)=111…11111(32个1)=UMAX。一个本该为-1的数变成了无符号数最大值,当i取任何不为0的数都发生了非法访问,自然出现了存储器错误,并且任何数都小于UMAX,出现判别式永远为真,进入死循环。解决办法有两种,做一个判断,当传入length<1,直接返回0 or 在之前就将length转化为int。

●浮点数

●定点数以及定点数的缺点

用10进制表示小数早已司空见惯,那么就会想要对二进制做同样的操作,为它也加上小数点。

但是如此的二进制小数,会出现一些问题不可避免

​ 整数部分小数部分二进制(Representation)

53/4101.112

27/810.1112

17/161.01112

很明显可以发现,只能准确的表示x/2k的小数,而不为x/2k只能近似。

​ 十进制小数部分二进制(Representation)

1/30.01010101[01]… 2

1/50.001100110011[0011]… 2

1/100.0001100110011[0011]… 2

而为什么会出现如上结果,就要知到1/3 和 1/5是如何计算的。

由此可见,当小数无法描述x/2k时,二进制小数便只能取近似值(多采用close to even(靠近偶数))。

这就暴露定点数的一个重要缺点 ---- 定点数无法标准化。也就是说,关于小数点的位置无法给出一个标准的定点数计算方式,不同小数点的位置给计算定点数增加了难度。与此同时,定点数表示的范围有限,32位的定点数,假设没有整数位,那么所能表示的小数的最小值为:2-32,而32位浮点数仅指数位便可以表示到2-126,由此不难看出,定点数虽然精度高,但标准化和范围大小都比较差。

所以此时便引出了浮点数来统一二进制小数的表示:

注:s:表示符号位,只用一个bit表示

M:表示尾数(significand)(frac)也表示小数位,即能准确表示小数位

E:表示指数位。

常用的float,double组成:

可以看出float有8位指数位,23位尾数位。指数最大可表示的范围为-127~126

浮点数所表示的一个范围:

可以得到,浮点数随着大小的不同被分为不同种类,接近0的称为Denormalized,较大的数字被分为Infinity。(关于Denormalized、Infinity等名词请自行了解,这里不再做过多的赘述)。

Denormalized到NaN的变化:

浮点数相加的公式:

浮点数的加法和乘法由于近似的原因,经常无法实现加法的结合律和乘法分配律,如下所示:

(3.14+le10)-1e10=0.0,因为3.14+1e10会舍入,3.14会丢失(1e10表示1*101010)

然而3.14+(1e10-1e10)=3.14

le20*(le20-le20)=0.0

le20le20-le20le20=NaN,由于溢出的关系,可见在数字大的情况下不满足加法结合律和乘法分配律。

最后,关于int,float,double之间相互转换可能的问题:

当在int,float以及double格式之间进行强制转换时,程序改变数值和位模式的原则如下(假设int为32位):

●从int转换成float,数字不会溢出,但可能被舍入。

●从int或float转换成double,因为double有更大的范围(也就是可表示值得范围),也有更高得精度(即有效位数),所以能保留精确得数值。

●从double转换成float,因为范围要小一些,所以值可嫩溢出为+∞或-∞。且由于精度较小,它还可能被舍入。

●从float或double转换成int,值将会向0舍入。例如1.999将转换为1。进一步说,值可能会溢出。C语言标准没有对这种情况指定固定的结果。而与Inter兼容的微处理器指定位模式[10…00](字长为ω时的TMinω)为整数不确定值。一个从浮点数到整数的转换,如果不能为该浮点数找到一个合理的整数近似值,就会产生一个这样的值。因此,表达式(int)+le10会得到-21483648,即从一个正值变成了一个负值。

参考博主:写代码的柯长(CSDN)、Jamesjiang2050(博客园)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。