浮点类型字面量和变量

一、浮点数转化为二进制

计算机存储和处理数据最终是转化为二进制形式,之前提到过整数字面量如何转化为二进制串(包括0、正整数和正整数取反加1)。
浮点数转化为二进制有它自己的规则:
1.浮点数的整数部分,仍按照整数转二进制的规则,除2取余(直到余数为0),倒序排列
2.浮点数的小数部分,采用乘2取整(直到小数部分为0),正序排列
例如123.45整数部分和小数部分分别转化为二进制串:
在这里插入图片描述
可见,整数部分一定能完全转化为二进制串(余数总会归0),但小数部分不一定能完全转化为二进制串(小数部分不一定归0)。因此,计算机是不能完全表示浮点数的(显然当小数部分是1 / 2^n时可以完全转化,但仍要考虑存储宽度的问题,因为可能要很多位才能完全表示这个小数部分),这就涉及到表示的浮点数的精度问题。
实际上一个浮点数通过上述方法分别计算出整数部分和小数部分二进制串之后并不能直接存储到计算机中,因为这样至少要能标志小数点的位置。
实际存储到计算机中的浮点数二进制串是经过IEEE754标准生成的,二进制串包括符号位、指数部分、位数部分,具体可以参考IEEE754标准
这里我们并不关心IEEE754标准如何生成浮点数的二进制串,只需要知道它并非是整数部分和小数部分分别转换成二进制串的结果。

二、浮点数字面量

C/C++中可以直接使用带小数点的浮点数字面量,如:

1.23;
0.005;

除此之外也能以科学计数法形式来使用浮点数字面量,如:

1.23E2; // 1.23*100 = 123.0
5.2E-3; // 5.2 / 1000 = 0.0052
-3.23E1; // -3.23*10 = -32.3

浮点数类型有如下三种:

类型 所占字节数
float 4
double 8
long double 8

浮点数字面量的默认识别类型是double,可以通过F、L后缀将一个浮点数字面量转化为其他类型。
一个浮点类型字面量被识别并转换成IEEE754标准的二进制串。如果将该字面量赋值给相同类型的浮点类型变量,则直接在该变量对应的内存中存放这个二进制串,例如:

float d = 123.45F; // float 4字节

变量中存放的二进制串:
在这里插入图片描述
如果我们按照浮点类型再将其输出:

printf("%f\n",d);

实际输出的结果为123.449997,并非给定的字面量值123.45。
前面提到,并非所有浮点数都能完全转化成二进制串,这里小数部分0.45就不能完全转换(有些即使能完全转换但需要的二进制位很多,但限于计算机对变量的数据宽度有限,有时也不能完全存储),这就涉及精确度的问题。
一个不能完全转换成二进制串的浮点数,只能尽可能地接近原浮点值。这就要人工指定接近的程度即精确度。
如果使用double类型表示123.45:

double d = 123.45;	// 8字节

则输出值为123.45000000000000,显然比float类型精确程度更高。这里123.45000000000000看似是和输入的字面量123.45是相等的,但实际上二者并不真正的相等,只是double有效位数比float多。如果继续增加变量存储浮点值的位数,如:

printf("%.20f\n",d); // 将有效位数设置为20

其输出结果为:
在这里插入图片描述
显然也不是精确值。
C/C++标准中指出:

The important rule to remember is that powers of two and integer multiples thereof can be perfectly represented. everything else is an approximation.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值