C/C++中浮点数的存储方式

2023-11-09

原文地址:**C/C++中浮点数的存储方式 作者:andyhzw

根据国际标准IEEE 754,任意一个二进制浮点数V可以表示成下面的形式:
   V = (-1)^s×M×2^E
  (1)(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
  (2)M表示有效数字,大于等于1,小于2。

  (3)2^E表示指数位。


IEEE关于浮点数的定义标准了,0.0f是一个特殊的数,阶码和尾数全为0来表示浮点的0,这是规定.


  举例来说,


        十进制的5.0,写成二进制是101.0,相当于1.01×2^2。那么,按照上面V的格式,可以得出s=0,M=1.01,E=2。

        十进制的-5.0,写成二进制是-101.0,相当于-1.01×2^2。那么,s=1,M=1.01,E=2。


  IEEE 754规定,对于32位(如 float的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。


        对于64位(如 double的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。



  IEEE 754对有效数字M和指数E,还有一些特别规定。
  前面说过,1≤M<2,也就是说,M可以写成1.xxxxxx的形式, 其中xxxxxx表示小数部分。IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等 到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存 24位有效数字。
  至于指数E,情况就比较复杂。
  首先,E为一个无符号整数(unsigned int)。这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出 现负数的,所以IEEE 754规定,E的真实值必须再减去一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。
  比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
  然后,指数E还可以再分成三种情况:
  (1)E不全为0或不全为1。这时,浮点数就采用上面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1
  (2)E全为0。这时,浮点数的指数E等于1-127(或者1-1023),有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
  (3)E全为1。这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);如果有效数字M不全为0,表示这个数不是一个数(NaN)


为什么0x00000009还原成浮点数,就成了0.000000?
  首先,将0x00000009拆分,得到第一位符号位s=0,后面8位的指数E=00000000,最后23位的有效数字M=000 0000 0000 0000 0000 1001。
  由于指数E全为0,所以符合上一节的第二种情况。因此,浮点数V就写成:
  V=(-1)^0×0.00000000000000000001001×2^(-126)=1.001×2^(-146)
  显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。


请问浮点数9.0,如何用二进制表示?还原成十进制又是多少?
  首先,浮点数9.0等于二进制的1001.0,即1.001×2^3。
  那么,第一位的符号位s=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130,即10000010。
  所以,写成二进制形式,应该是s+E+M,即0 10000010 001 0000 0000 0000 0000 0000。这个32位的二进制数,还原成十进制,正是1091567616。



十进制的0.5,写成二进制是0.1,相当于1.0* 2^(-1)。那么,s=0,M=1.0,E=-1。

    则:1≤M<2,只需保存M中小数点后的数值,此时为 0,则 第22位为0,填充第0~21位为0;

            E = -1;保存时为 127+(-1)=126(十进制)=111 1110(二进制)

    二进制结果为: 符号     阶码        有效数值

                            0 01111110  00000000000000000000000



测试代码:


点击(此处)折叠或打开

  1. #include <iostream>
  2. using namespace std;


  3. int main(void)
  4. {
  5.     float a = 125.5f;
  6.     cout << (int)<< endl;
  7.     cout <<hex<< (int&)<< endl;
  8.     cout <<"addr:"<<&a<<" " <<a<<endl;
  9.     cout << boolalpha << ( (int)== (int&)) << endl<<endl; 

  10.     float b = 1.0f;
  11.     cout << (int)<< endl;
  12.     cout <<hex<< (int&)<< endl;
  13.     cout <<"addr:"<<&b<<" " <<b<<endl;
  14.     cout << boolalpha << ( (int)== (int&)) << endl<<endl; 

  15.     float c = 0.0f;
  16.     cout << (int)<< endl;
  17.     cout <<hex<< (int&)<< endl;
  18.     cout <<"addr:"<<&c<<" " <<c<<endl;
  19.     cout << boolalpha << ( (int)== (int&)) << endl<<endl; 

  20.     float d = 0.5f;
  21.     cout << (int)<< endl;
  22.     cout <<hex<< (int&)<< endl;
  23.     cout <<"addr:"<<&d<<" " <<d<<endl;
  24.     cout << boolalpha << ( (int)== (int&)) << endl<<endl; 
  25.     return 0;
  26. }



(int&)a == static_cast<int&>(a)
(int)&a == reinterpret_cast<int>(&a);
(int&)a 不经过转换, 直接得到a在内存单元的值
(int)a a在内存中的值转换成int类型


结果显示如下:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++中浮点数的存储方式 的相关文章

  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • 赋值运算符和复制构造函数有什么区别?

    我不明白C 中赋值构造函数和复制构造函数之间的区别 是这样的 class A public A cout lt lt A A lt lt endl The copy constructor A a b The assignment cons
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • 有什么工具可以说明每种方法运行需要多长时间?

    我的程序的某些部分速度很慢 我想知道是否有我可以使用的工具 例如它可以告诉我可以运行 methodA 花了 100ms 等等 或者类似的有用信息 如果您使用的是 Visual Studio Team System 性能工具 中有一个内置分析
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • gdb 在 docker 上立即退出“进程已完成,退出代码 1”或 lldb“数据包返回错误 8”。另外:如何在 docker 中允许进行 C++ 调试

    这花了我一整天的时间才找到 所以我将其发布以供将来参考 我正在 docker 镜像上开发 C 我正在使用克利翁 我的代码是在调试模式下编译的 并且在运行模式下运行良好 但是当尝试调试时 进程会立即退出 并显示非常丰富的信息 Process
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 内核开发和 C++ [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从我know https stackoverflow com questions 580292 what languages are windo
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • mbp适合程序员_程序员入手mbp一月感受

    网上很多人推荐程序员使用macbookpro 说是最适合程序员的电脑 刚好新公司需要使用mac 趁着暑假教育优惠 入手了2020 13寸 2 0Ghz的mbp 一个月使用感受大致如下 1 macos和服务器上的linux系统环境差异比较大
  • R--基础知识总结

    R程序包的安装和加载 install packageS TSA library TSA R向量 vector 数值向量 1 赋值 x lt c 1 2 3 4 assign x c 1 2 3 4 x c 1 2 3 4 x lt 2 1
  • 【SpringBoot应用篇】SpringBoot+MybatisPlus集成国产DM8(达梦)数据库

    SpringBoot应用篇 SpringBoot MybatisPlus集成国产DM8 达梦 数据库 简介和安装 基本概念介绍 SpringBoot MP整合DM8 pom yml Address AddressMapper 启动类 测试类
  • CESM:手动inputdata

    参考教程 CESM2笔记 porting 新机器移植 cesm2创建case J同学的大气笔记的博客 CSDN博客 ftp链接失效 试试通过cmd下载cam学习材料 cesm为什么不能直接下载数据 J同学的大气笔记的博客 CSDN博客 ca
  • QTreeView默认选中某个节点的方法

    最近使用Qt做个界面 使用了QTreeView显示一个树形数据 想在界面打开时 默认选中某个节点 网上搜索全是MFC的TreeView的 在这里记一下QTreeView的方法 QTreeView的基本使用 QStandardItemMode
  • Django知识点

    MTV M 模型 model 主要操作数据库等 T 模板 template 代替了MVC模型的view 主要定义前端 调用view等 V 视图 view 代替MVC模型的controller 主要接受用户请求 调用model 调用templ
  • Qt扫盲-QVariant理论使用总结

    Qt扫盲 QVariant理论使用总结 一 概述 二 使用用例 三 关于GUI类型的说明 四 连续使用canConvert 和convert 一 概述 QVariant 是一个用来存放变体数据的工具类 因为c 禁止 union 包含具有非默
  • 深度学习和日常代码中遇到的报错汇总及解决方案,持续更新中。。。。

    本文是深度学习和日常代码中遇到的报错汇总 因时间比较久 暂时都没有图片 只有文字描述 解决方案也大多参考网上的解决方案 有些有用 有些没有效果 本文章中的问题 也仅是本人遇到的问题 使用列举的方案已经解决 1 报错 RuntimeError
  • 【无监督学习】遗传算法Genetic Algorithm(含代码实现)

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Macbook Pro 突然无声音播放,硬件设备都没问题。

    打开Terminal 终端 就是黑色框框那个 跟Windows cmd差不多那个 输入命令 sudo killall coreaudiod 因为看到好多人说重置那个SMC 浪费时间 先用这个命令试试 基本可以解决
  • 纯前端css实现酷炫loading动画

    纯前端css实现酷炫loading动画 1 平滑加载 2 按步加载 3 虚线加载 4 电池加载 5 内嵌加载 6 斑马线加载 7 水柱加载 8 信号加载 9 四个动点加载 1 平滑加载 div class progress 1 div pr
  • MVP 实现登录注册

    http blog csdn net dfskhgalshgkajghljgh article details 51317956
  • react+antd系列之日期选择框DatePicker

    1 默认时间
  • stm32cubemx生成不了keil工程文件_STM32cubeMX教程定时器实现定时1秒LED闪烁

    软件 STM32CubeMX V4 25 0 keil u5 固件库版本 STM32Cube FW F1 V1 6 1 硬件 OneNet 麒麟座V1 4 在STM32CubeMX中新建项目 选择正确的MCU型号 首先设置RCC和SYS 如
  • 若依图片文件上传

    1 前端代码 使用若依自带的
  • Grafana ALert功能使用webhook,并预警数据信息

    使用webhook预警的时候如果能够同时获取预警的数据信息是最好不过的 这里我们就来看下怎么获取这些东西 数据源依然选用InfluxDB 具体配置过程可以参考前边两篇文章 现在从webhook配置开始 无参对接 在Grafana的Alert
  • LeetCode108.将有序数组转换为二叉搜索树

    题目来源 108 将有序数组转换为二叉搜索树 力扣 LeetCode 二叉搜索树定义 二叉搜索树 Binary Search Tree 又 二叉查找树 二叉排序树 它或者是一棵空树 或者是具有下列性质的 二叉树 若它的左子树不空 则左子树上
  • 2023华为OD机试真题【处理器问题/深度优先搜索】

    题目描述 某公司研发了一款高性能AI处理器 每台物理设备具备8颗AI处理器 编号分别为0 1 2 3 4 5 6 7 编号0 3的处理器处于同一个链路中 编号4 7的处理器处于另外一个链路中 不同链路中的处理器不能通信 现给定服务器可用的处
  • mysql 读写分离

    读写分离引入时机 大多数互联网业务中 往往读多写少 这时候数据库的读会首先成为数据库的瓶颈 如果我们已经优化了SQL 但是读依旧还是瓶颈时 这时就可以选择 读写分离 架构了 读写分离首先需要将数据库分为主从库 一个主库用于写数据 多个从库完
  • C/C++中浮点数的存储方式

    原文地址 C C 中浮点数的存储方式 作者 andyhzw 根据国际标准IEEE 754 任意一个二进制浮点数V可以表示成下面的形式 V 1 s M 2 E 1 1 s表示符号位 当s 0 V为正数 当s 1 V为负数 2 M表示有效数字