代码之谜(四)- 浮点数(从惊讶到思考)

在『代码之谜』系列的前几篇文章中,很多次出现了浮点数。 浮点数在很多编程语言中被称为简单数据类型,其实,浮点数比起那些复杂数据类型(比如字符串)来说, 一点都不简单。

单单是说明 IEEE浮点数 就可以写一本书了,我将用几篇博文来简单的说说我所理解的浮点数,算是抛砖引玉吧。

一次面试

记得多年前我招聘 Java 程序员时的一次关于浮点数、二分法、编码的面试, 多年以后,他已经称为了一名很出色的程序员。 每次聚会他都会告诉我,“那次面试彻底改变了我的过去的学习方式, 我以前只是盲目接受知识,根本就没有自己思考过, 那次对话,比我大学四年学到的知识都多”。

我看他简历上写到读过《信息论》才谈了很多关于二分法以及编码的话题, 整个过程大概3个小时——这是我面试时间最长的一次。

因为时间久远,我把一些我能回忆起来的关于浮点数的内容整理在这篇博客中。

格式说明:

所有我说的话,都放在引用里面。他的话放在了引号(“”)里面。没有加引号的是我的心理活动或者说明。

浮点数个数

在 8 位计算机上,浮点数一共有多少个呢?

“8 位的好像太过时了,现在主流的是 32 位的,好像可以表示3 x 10^38。”

果然不出我所料,很多毕业生都把计算机学成了文科,他们不是在学习理论知识,而是接受/背诵这些知识。

8 位计算机可以表示的整数是多少个呢?

“这个简单,2的8次方,应该是 256 个。N 位计算机表示的整数就是 2 的 N 次方。”

他回答时显得很兴奋,因为他终于可以反驳我的观点了,他没有把计算机当作死记硬背的学科。

8 位计算机,或者说8bit 可以表示 2^8 个整数。 如果用这 8bit 来表示字符,可以表示多少个呢?

“呵呵,当然也是 2 的 8 次方了,否则就没有必要再发明16位或者32位的 unicode 去表示汉字了。”

如你刚才所说,8bit 可以表示 3^38 个浮点数。那么你估算一下,2bit 可以表示多少个浮点数呢?

“既然 2bit 可以表示 4 个整数,浮点数嘛肯定比这个多,最少也得能表示 10 几个浮点数吧。”

好吧,按照你的思路,我说几个数。

  • 0总该有吧,用 00 表示。
  • 1 用 01 表示
  • 2 用 10 表示
  • 3 用 11 表示

现在你把 0.4 给我表示出来?

『他思索了片刻』“哦。我明白了,2bit 可以表示 4 个数,不管是整数、小数或者字符,就算是用 2bit 表示苹果,我们也只能表示 4 个,如果想要表示更多,就得用更多的 bit 位。”

虽然他在简历中写到读过《信息论》,他对N bit可以表示的信息量是 2^N肯定没有完全理解,或者只是被动接受了这个定理。

过了一会儿他又继续说:“按照这个逻辑,8bit 只能表示 256 个浮点数了,这也太少了。 我有点糊涂了,浮点数的表示范围一般都得几万甚至几亿啊。”

浮点数精度

于是我在 firebug 里面写了几行代码(可以在本系列第一篇的序言部分找到这些代码)。

0.2 + 0.4

0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1

“这怎么可能呢?JS 居然这么不严格?”

显然他把这种现象归结于 js(谢天谢地,他没有把罪过加在 firebug 身上)。 于是我用 Java 重写了上面的代码,这回他只剩目瞪口呆了。

既然他已经开始惊讶,那么下一步就是思考。我又稍作了解释:

任何语言都宣称他们的浮点数的表示范围是 3 x 10^38,这个数到底多大呢?目前所知宇宙的年龄是 1.373 x 10^10 年。

但是 32bit 最多只能表示 2^32 个数,大约是 4 x 10^9。

对比一下你就会发现令人震惊的结果。 如果把浮点数的范围比做地球,那么可以精确表示的浮点数还不到一粒芝麻大。

“这么说,0.2+0.4 是因为他不能够精确表示,所以出现了计算错误的现象。那在编程中如何避免这种问题呢?”

用定点数表示小数。

浮点数等价于小数吗

“定点数不是整数吗?定点数怎么表示小数啊?”

很显然,有一个理论性概念错误。他没有真正理解什么是定点,什么是浮点。

浮点数可以表示整数吗?比如,float a = 2 可以吗?

“可以是可以,这个 2 在计算机里面应该存储的是 2.0 吧?”

计算机肯定没有存储 2.0。百分之一万的肯定。计算机存储的是0、1串。呵呵。

“我觉得浮点数应该不会存储整数的2,他存储的应该是小数的2.0,然后转换成0、1串,是这样吗?”

他一连问了我几个问题,使我感觉到,我不是在面试,而是在上课。

整数和小数是数学里面的概念,在计算机中,只有定点数和浮点数,没有整数和小数。

定点数在课本里如何定义的?

“忘了,只知道定点数就是整数,浮点数就是小数。好像老师也是这么讲的。”

那是因为你们老师不是我,如果我当老师,肯定不会这么教学生。『笑』

定点、浮点,“点”是什么意思?“点”就是小数点。 把小数点固定,通常固定在最右面,就是定点数。 把小数点浮动,就是浮点数。浮点在哪儿?这个在 IEEE 浮点数标准里面定义的。

回到前面话题,如何精确的表示小数呢?其中一种方案就是定点数。

拿 8bit 举例吧。我们可以把小数点定在中间,用 4bit 表示整数部分,4bit 表示小数部分。 这样构造方式(专业点我们称他为数据结构,一般语言把整数和小数称为简单数据类型,其实他们一点都不简单,而且比那些成了复合数据类型的字符串都要复杂的多),我们可以精确的表示256个小数。


在下一章,我们将构造一个 8bit 的浮点数表示形式,来深入探索浮点数不为人知的秘密。 我称它为 JJFN-134(JustJavac Float Notation,justjavac浮点数表示法),1bit符号,3bit指数,4bit尾数。

用于将Modbus通信中截取后四字节的十六进制数转换为单精度浮点数(源码) 用于将Modbus通信中感应器返回的数据截取后的数据处理成浮点数,目前只弄了四字节的十六进制数转换为单精度浮点数。 立即下载

相关推荐

C# 串口通讯截取4位字节数据16进制转浮点型输出

本程序是用串口工具读取一个电流表的通讯程序的源代码,要求将返回的4位字节数据()16进制)转浮点型实时输出到窗体上

聊聊 8 位浮点数

越来越多的神经网络模型在部署的时候采用 8 位浮点数,感到有些好奇,所以粗略了解一下,聊聊这个话题。 ## 1.浮点数的格式 先说说浮点数的表示方法。任意二进制数N可以写成 N = 2^e * M 的形式,其中 M 称为浮点数的尾数,是一个纯小数。e 是比例因子的指数,称为浮点数的指数,是一个整数。比例因子的基数 2 对二进记数制的机器是一个常数。 我们参照 IEEE R32.24 标准,看看 float32 的格式:

程序猿视角 1万+

国密SKF库数字签名全解析:SM2签名与验证的详细实现

本文详细解析了基于国密SKF库实现SM2数字签名与验证的全过程。内容涵盖SKF库环境搭建、设备初始化、PIN码验证、SM2签名生成以及纯软件与SKF库两种验证方式的详细实现,为开发者提供了一份实用的国密算法开发指南。

weixin_29303701的博客 323

代码之谜(五)- 浮点数(谁偷了你的精度?)

****光棍节加长版**** 如果我告诉你,中关村配置最高的电子计算机的计算精度还不如一个便利店卖的手持计算器,你一定会反驳我:「今天写博客之前又忘记吃药了吧」。 你可以用最主流的编程语言计算 0.2 + 0.4,如果你使用的是 Chrome、FireFox、IE 8+,可以按 F12 键,然后找到 「控制台」,输入上面的 表达式 0.2 + 0.4,回车。 然后再用最简陋的计算器(如果...

justJavaC的专栏 827

gephi生成网络关系图_路网拓扑重建专题 (3) 网络图生成

城市道路网建模在获得基础路网之后,需要考虑道路交通网络的描述与表达问题。网络是将现实世界中的事物及其关系进行适当的抽象,构造成由节点和边按照一定规则组成的形式。一个实体网络可以由有限个“节点”集合与“边”集合构成的图表示,即网络表示为。对于一个由个节点组成的无权复杂网络,该图有邻接矩阵,这里。根据研究对象不同,建模方法主要包括原始法[1]和对偶法[2]两种,见图1,字母a-j为交叉口编号...

weixin_39761195的博客 3502

Anomalib实战指南:从零开始构建自定义异常检测数据集

本文提供了一份详细的Anomalib实战指南,指导用户从零开始构建自定义异常检测数据集。文章深入解析了数据准备的核心步骤、目录结构规范,并对比了PatchCore与FastFlow等关键模型的适用场景。通过清晰的代码示例,手把手演示了环境配置、模型训练与推理评估的全流程,旨在帮助开发者快速掌握这一工业视觉异常检测利器,有效解决实际生产中的缺陷识别难题。

weixin_29054245的博客 643

8位浮点数的表示法

32位浮点数的计算机内部表示是由IEEE754标准定义的,参考文献相当多。 简单来说,是由符号位、指数位(阶码)和小数部分共同定义的。 https://www.h-schmidt.net/FloatConverter/IEEE754.html IEEE754规范中只定义了32位(float)和64位(double)浮点的表示法,好像还有扩展的16位、128位的浮点数表示法,但用的场景不多。 8位浮点数表示法,并没有相关规范,详细内容搜索IEEE754规范,并仔细阅读。 /// +----+--------

申龙斌的程序人生 5754

用Cadence IC618和TSMC 180nm工艺,从零仿真一个2.4GHz双平衡吉尔伯特混频器

本文详细介绍了使用Cadence IC618和TSMC 180nm工艺从零开始仿真2.4GHz双平衡吉尔伯特混频器的完整流程。涵盖设计环境搭建、原理图设计、仿真配置、性能验证及版图设计等关键步骤,特别适合射频集成电路设计的学习者和实践者参考。通过实操技巧与工艺库结合的工程实践,帮助读者掌握混频器设计的核心技术。

weixin_30328063的博客 550

8位浮点数能表示的所有小数

0 0-000-0000 +0.0000×2-2 +0.0 +0.0 ,+Zero1 0-000-0001 +0.0001×2-2 +0.000001 +0.015625 2 0-000-0010 +0.0010×2-2 +0.00001 +0.03125 3...

全栈空间 1013

JMeter 压测实战全教程

脚本结构:测试计划 → 线程组 → HTTP 请求 → 监听器运行方式:图形化调试,命令行生产压测核心指标:QPS、RT、错误率、CPU、GC。

weixin_48309090的博客 651

LabVIEW Modbus通讯实战:从安装库到读写寄存器的完整避坑指南

本文详细介绍了LabVIEW与Modbus通讯的完整实战指南,从安装库文件到读写寄存器的全流程操作,帮助开发者避开常见问题。通过虚拟串口配置、主机配置实战和高级调试技巧,提升工业自动化领域的通讯效率与可靠性。

milk8的博客 738

代码之谜(零) - 其实,你不懂代码

2012年9月28日 13时32分 新增 最近看本文评论,争议很多,我先说说这篇文章的前世今生吧。 我原文标题是『代码之谜 - 开篇/前言/序』,副标题是『其实,你不懂代码』,本来打算用“其实,代码中的运算符不等价于数学符号”。原文我写于2010年底,当时写在 evernote 中,用了”群“、”域“、”集合“、”关系“的概念解释了计算机中用二进制表示的离散的数和现实中连续的数之间...

iteye_6378的博客 312

knowhere | 第一课:项目导论与环境搭建

摘要 本课程是Knowhere项目的第一课,重点介绍项目整体架构和开发环境搭建。Knowhere定位为AI Agent的文档记忆基础设施,通过解析多格式文档并保留结构化信息(如章节层级、表格语义等),为Agent提供可导航的文档知识。项目采用Python monorepo结构,核心包括: apps/api:FastAPI服务,处理HTTP请求和流程调用 apps/worker:Celery服务,执行文档解析等耗时任务 packages/shared-python:共享基础设施层 课程明确了各层职责边界,并推

weixin_43674738的博客 151

【转】代码之谜(四)- 浮点数(从惊讶到思考)

在『代码之谜』系列的前几篇文章中,很多次出现了浮点数。 浮点数在很多编程语言中被称为简单数据类型,其实,浮点数比起那些复杂数据类型(比如字符串)来说, 一点都不简单。 单单是说明 IEEE浮点数 就可以写一本书了,我将用几篇博文来简单的说说我所理解的浮点数,算是抛砖引玉吧。 一次面试 记得多年前我招聘 Java 程序员时的一次关于浮点数、二分法、编码的面试, 多年以后,他已经称为

wfx的专栏 402

PCB仿真软件:Altium Designer_(18).PCB设计中的热管理

在PCB设计中,热管理是一个至关重要的环节。随着电子设备的集成度越来越高,功耗和发热量也随之增加,不合理的热设计可能导致电路板过热,从而影响电路的性能和可靠性。热管理不仅能够提高电路板的使用寿命,还能确保电路在各种环境条件下的稳定工作。本节将详细介绍如何在Altium Designer中进行有效的热管理,包括热分析、热设计和热仿真等关键步骤。

kkchenjj的博客 1985

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

[乐意黎转载]代码之谜--justjavac(迷渡)

代码之谜 http://justjavac.com/codepuzzle.html 代码之谜(零)- 开篇/前言/序  http://justjavac.com/codepuzzle/2012/09/25/codepuzzle-introduction.html 代码之谜(一)- 有限与无限 从整数的绝对值说起 http://justj

打杂人-aerchi 794

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【转】代码之谜(五)- 浮点数(谁偷了你的精度?)

****光棍节加长版**** 如果我告诉你,中关村配置最高的电子计算机的计算精度还不如一个便利店卖的手持计算器,你一定会反驳我:「今天写博客之前又忘记吃药了吧」。 你可以用最主流的编程语言计算 0.2 + 0.4,如果你使用的是 Chrome、FireFox、IE 8+,可以按 F12 键,然后找到 「控制台」,输入上面的 表达式 0.2 + 0.4,回车。 然后再用

wfx的专栏 389

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

上一篇: 精通one,学习another,关注next
下一篇: 通向架构师的道路(第二十一天)万能框架spring(三)之SSH
iteye_6378
博客等级 码龄8年 21粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值