浮点数

来源:互联网 发布:openwrt与linux 编辑:程序博客网 时间:2024/04/29 12:14

浮点数的表示法

浮点数在内存中的存储方式为:符号位、指数、尾数

类型 符号位 指数 尾数 float 1位(第31位) 8位(第23-30位) 23位(第0-22位) double 1位(第63位) 11位(第52-62位) 52位(第0-51位)

十进制浮点数在计算机内部的转换

转换步骤:
1. 将浮点数的整数部分和小数部分分别转换为二进制
2. 用科学计数法表示二进制浮点数
3. 计算指数偏移后的值

注意:
  计算指数时需要加上偏移量,而偏移量的值与类型有关。
  示例:对于指数6,偏移后的值如下:
  float:127 + 6 = 123
  double:1023 + 6 = 1029

转换举例:8.25在内存中的float表示

8.25的二进制表示:1000.01 -> 1.00001 * (2^3)
 符号位:0
 指数:3 + 127 = 130 -> 10000010
 尾数:00001

故内存中8.25的float表示为:
    0 10000010 00001000000000000000000 -> 0x41040000

浮点数隐藏的秘密(今天的主要内容)

首先,我们来看一个有趣的问题。

int类型的范围:[-231, 231 - 1]
float类型的范围:[-3.4 * 1038, 3.4 * 1038]

思考:
int和float都占4个字节,为什么float表示的范围要远大于int?

要弄清这个问题,需要知道以下几点:

1、数据类型所占用的字节数仅仅决定了该类型所能表示的具体数字的个数,而不是数的最大值和最小值
2、float所能表示的数字个数和int相同
3、float可表示的数字之间是有间隙的,是不连续的,故它能表示的范围比int大得多

由以上几点我们可以得出结论:float只是一种近似的表示法,不能作为精确值使用。实际上,double与float具有相同的内存表示法,所以以上几点同样适用于double,只不过double占用的位数比float多,因此其精度相对于float要高。

在本篇博文结束前,写一段代码验证上述结论:

#include <stdio.h>int main(){    float f = 3.1415F;    float f1 = 123456789;    printf("%0.10f\n", f);  //期望值:3.1415000000    printf("%0.10f\n", f1); //期望值:123456789.0000000000    return 0;}

在linux中编译运行,结果如图,与预期值均不符合,说明float表示的值的确是有间隙、不连续的。
这里写图片描述

0 0
原创粉丝点击