float与double的范围和精度_double范围-程序员宅基地

技术标签: C语言  c语言  

float和double的区别

  1. double是双精度浮点数,内存占8个字节,有效数字16位,表示范围是-1.79E+ 308~-1.79E+308。
    float是单精度浮点数,内存占4个字节,有效数字8位,表示范围是 -3.40E+38~3.40E+38。
  2. 两者处理速度不同,CPU处理float的速度比处理double快。double的精度高,double消耗内存是float的两倍。
  3. 如果不声明,小数默认是double类型,用float时需要进行强转,或者在小数后加上f。

float与double的范围和精度

1 范围

float和double的范围是由指数的位数来决定的。

float的指数位有8位,而double的指数位有11位,分布如下:

float:

1bit(符号位) 8bits(指数位) 23bits(尾数位)

double:

1bit(符号位) 11bits(指数位) 52bits(尾数位)

在数学中,特别是在计算机相关的数字(浮点数)问题的表述中,有一个基本表达法:
value of floating-point = significand xbase ^ exponent , with sign
译为中文表达即为:
(浮点)数值 = 尾数 × 底数 ^ 指数,(附加正负号)

于是,float的指数范围为-127 ~ 128,而double的指数范围为-1023 ~ 1024,并且指数位是按补码的形式来划分的。其中负指数决定了浮点数所能表达的绝对值最小的数;而正指数决定了浮点数所能表达的绝对值最大的数,也即决定了浮点数的取值范围。

float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。

2 精度

float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。

float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;

double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

单精度类型(float)和双精度类型(double)存储

在C 语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用 32bit, double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范 的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。

R32.24和R64.53的存储方式都是用科学计数法来存储数据的,科学计数法是将所有的数字转换成(±)a.b * 10^c的形式,其中a的范围是1到9共9个整数,b是小数点后的所有数字,c是10的指数。而计算机中存储的都是二进制数据,所以存储的数字都要先转化成(±)a.b * 2^c ,由于二进制中最大的数字就是1,所以表示法可以写成(±)1.b *2^c 的形式,要想存储小数就只需要存储(±),b和c就可以了。

float的存储正是将4字节32位划分为了3部分来分别存储正负号,小数部分和指数部分的:

  1. Sign(1位):用来表示浮点数是正数还是负数,0表示正数,1表示负数。
  2. Exponent(8位):指数部分。即上文提到数字c,但是这里不是直接存储c,为了同时表示正负指数以及他们的大小顺序,这里实际存储的是c+127。
  3. Mantissa(23位):尾数部分。也就是上文中提到的数字b

三部分在内存中的分布如下,用首字母代替类型

S E E E E E E E E M M M M M M M M M M M M M M M M M M M M M M M
0 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1

double的存储正是将8字节64位划分为了3部分来分别存储正负号,小数部分和指数部分的:

  1. Sign(1位):用来表示浮点数是正数还是负数,0表示正数,1表示负数。
  2. Exponent(11位):指数部分。即上文提到数字c,但是这里不是直接存储c,为了同时表示正负指数以及他们的大小顺序,这里实际存储的是c+127。
  3. Mantissa(52位):尾数部分。也就是上文中提到的数字b

三部分在内存中的分布如下,用首字母代替类型

S E E E E E E E E E E E M M M M M M M M M M M M M M M M M M M M
0 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0
M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M
1 1 1 1 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 1 1 0 1 1

float存储示例

以数字6.5为例,看一下这个数字是怎么存储在float变量中的:

先来看整数部分,模2求余可以得到二进制表示为110。

再来看小数部分,乘2取整可以得到二进制表示为.1(十进制的小数转换为二进制,主要是小数部分乘以2,取整数部分依次从左往右放在小数点后,直至小数点后为0)。

拼接在一起得到110.1然后写成类似于科学计数法的样子,得到1.101 * 2^2。

从上面的公式中可以知道符号为正,尾数是101,指数是2。

符号为正,那么第一位填0,指数是2,加上偏移量127等于129,二进制表示为10000001,填到2-9位,剩下的尾数101填到尾数位上即可

S E E E E E E E E M M M M M M M M M M M M M M M M M M M M M M M
0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

内存中二进制数01000000 11010000 00000000 00000000表示的就是浮点数6.5

而双精度浮点数的存储和单精度的存储大同小异,不同的是指数部分和尾数部分的位数。所以这里不再详细的介绍双精度的存储方式了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43791071/article/details/122361036

智能推荐

解决STM32F1 系列复位后RTC日期为2000-01-01_stm32f1 复位后rtc日期不对-程序员宅基地

文章浏览阅读5.2k次,点赞3次,收藏12次。问题:STM32F1中RTC 不像 F4中,是一个单独模块。其就是一个计数器,查看HAL库中时间和日期的设置发现,在日期设置的时候,HAL库并没有将日期换算为计数器的值。库源码如下日期设置:HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format){ uin..._stm32f1 复位后rtc日期不对

MERGE语法详解-程序员宅基地

文章浏览阅读635次,点赞2次,收藏15次。merge语法是根据源表对目标表进行匹配查询,匹配成功时更新,不成功时插入。其基本语法规则是merge into 目标表 ausing 源表 bon(a.条件字段1=b.条件字段1 and a.条件字段2=b.条件字段2 ……) when matched then update set a.更新字段=b.字段when not macthed then inse..._merge into限制目标表字段

pythonocc基础使用:1.读取/写入brep,iges,step,stl文件_pythonocc-core 读取step-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏32次。待写_pythonocc-core 读取step

Java数据类型-程序员宅基地

文章浏览阅读2.4w次,点赞60次,收藏62次。文章目录定义分类计算机存储单元Java基本数据类型图数据类型转换定义Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。分类基本数据类型数值型整数类型(byte,short,int,long)浮点类型(float,double)字符型(char)布尔型(boolean)引用数据类型类(class)接口(..._java数据类型

mysql hivedb_hive使用mysql localstore方式连接Access denied for user 'hive'@'localhost' to database...-程序员宅基地

文章浏览阅读252次。mysql> create user 'hive' identified by 'hive'; --创建用户Query OK, 0 rows affected (0.00 sec)mysql> grant all privileges on *.* to 'hive@localhost' with grant option; --localhost不可少,否则启动bin..._access denied for user 'hive'@'localhost

ABAP 去除字符串某个字段(去掉的金额逗号例子)_abap怎么去掉千分符-程序员宅基地

文章浏览阅读5.5k次,点赞5次,收藏14次。ABAP 去除字符串某个字段(去掉的金额逗号例子)实际程序中,我们有很多需求是要把excel的数据导入SAP数据之中去,但是这金额是带有千分位逗号的,比如(2,602,568.71)如果要把这个值赋值给金额字段,那程序会直接报错。解决方法一 :解决数据源头上的问题,直接把数据的格式换成数值。解决方式二:在ABAP代码上进行数据处理和校验(业务有时候就是那么无理取闹)1.先上代码DATA: lv_je TYPE string VALUE '2,602,568.71' .DO 10 TIMES. _abap怎么去掉千分符

随便推点

100道python经典练习题_100道 python练习下载-程序员宅基地

文章浏览阅读6.8w次,点赞140次,收藏596次。链接:https://pan.baidu.com/s/1K0iuZKJukLoGQ8OBy7xq1Q提取码:2s6q链接长期有效,如有疑问,欢迎评论区交流。_100道 python练习下载

大麦路由器dw22d不拆机刷breed和openwrt_大麦dw22d改无线打印服务器-程序员宅基地

文章浏览阅读1.6w次,点赞17次,收藏29次。@[TOC]大麦路由器DW22D不拆机刷Breed和OpenWrt大麦路由器DW22D不拆机刷Breed和OpenWrt1.进入http://192.168.10.1/upgrade.html2.开启ssh,在密码框中输入以下内容,最后面有一个空格123 | echo 6c216b27c8c9b051106c969e2077d4e9 > /ezwrt/bin/upgrade_passwd 3.点确定,然后提示密码错误没关系4. 再次打开 http://192.168.10.1/upgra_大麦dw22d改无线打印服务器

re学习笔记(75)BUUCTF - re - [ACTF新生赛2020]Splendid_MineCraft_buuctfsplendid-mine-程序员宅基地

文章浏览阅读454次。[ACTF新生赛2020]Splendid_MineCraftmain函数strtok是用分隔符划分字符串,根据+5 +9差4个,再加上+9强转为WORD,得到每组字符是4+2=6个flag格式为ACTF{xxxxxx_xxxxxx_xxxxxx}36行跳转到数据段先是对数据段进行异或0x72h解密解密后,F5得到两个数异或+35与第一段输入进行比较第二段也是一个smc自解密第二段主要代码。ebx为用户输入与(0x83+i)异或得到的下标根据eax进行索引查表。得到的bl与第二_buuctfsplendid-mine

《深入理解Java虚拟机 JVM高级特性与最佳实践》读书笔记--JAVA自旋锁与自适应自旋锁_为什么自旋等待的方式避免了线程忙等-程序员宅基地

文章浏览阅读315次。自旋锁释义:请求锁的线程(假设为线程A)再未获得锁的时候,不进入阻塞状态,而是让它「再执行一会」即占用CPU一会,看看持有锁的线程是否很快释放锁资源。但是为了让这个线程A进入「等待」的状态,需要让它执行一个忙循环(自旋),这项技术称为自旋锁。自旋锁的优劣势分析线程A的状态切换是由系统进行的,而这个过程则会消耗系统资源的,如果请求锁的「忙循环」时在一个很小的时间片之内就得到锁,..._为什么自旋等待的方式避免了线程忙等

西门子S7系列PLC与现场设备(仪表)通讯解决方案_西门子sm422-程序员宅基地

文章浏览阅读1.1k次。针对西门子S7系列的PLC,SiboTech智能、多功能、紧凑型通用串口/PROFIBUS-DP网关(PM-160)为建立西门子PLC与现场RS232/485/422设备的连接提供了理想解决方案:PM-160能够解决西门子PLC对现场各种RS232/485/422设备的实时监控,如:具有Modbus协议(或者用户自定义非标协议)接口的变频器、电机启动保护装置、智能高低压电器、电量测量装置、各种变送器、智能现场测量设备及仪表等等;PM-160也能够解决现场DCS系统(Modbus主站设备)和PLC之间的实_西门子sm422

ubuntu15.04配置php,Linux_Ubuntu 15.04上安装Justniffer的详细教程,Justniffer 是一个可用于替代 Snor - phpStudy...-程序员宅基地

文章浏览阅读81次。Ubuntu 15.04上安装Justniffer的详细教程Justniffer 是一个可用于替代 Snort 的网络协议分析器。它非常流行,可交互式地跟踪/探测一个网络连接。它能从实时环境中抓取流量,支持 “lipcap” 和 “tcpdump” 文件格式。它可以帮助用户分析一个用 wireshark 难以抓包的复杂网络。尤其是它可以有效的帮助你分析应用层流量,能提取类似图像、脚本、HTML 等..._snort 替代

推荐文章

热门文章

相关标签