valid floating point value什么意思_为什么 0.1 + 0.2 = 0.30000...0004,是否很多问号?

JavaScript 作为一门诞生自上个世纪 90 年代的编程语言,从诞生之初就因为诡异的隐式类型转换等原因被黑,很多 JavaScript 的开发者还会吐槽浮点数加法的『奇葩』问题:

为什么 0.1 + 0.2 在 JavaScript 中不等于 0.3

相信很多人都对这个问题的答案有一个大概的认识,但是都没有深入研究过,这个问题的答案让 William Kahan 在 1989 年获得图灵奖

> 0.1 + 0.2
0.30000000000000004

其实有上述问题的不止 JavaScript 一门编程语言,几乎所有现代的编程语言都会遇到上述问题,包括 Java、Ruby、Python、Swift 和 Go 等等,你可以在 https://0.30000000000000004.com/ 中找到常见的编程语言在计算上述表达式的结果。

这不是因为它们在计算时出现了错误,而是因为浮点数计算标准的要求。

d4a510e2995c5e0afc9597affdb8e56f.png
floating-point-math

图 1 - 常见的浮点数『错误』

从最开始接触 C 语言编程,作者就接触到了浮点数 float,然而在很长一段时间中,作者都将编程中的浮点数和数学中的小数看做同一个东西,不过当我们重新审视它们时,会发现这两个概念的不同之处。

  • 编程中的浮点数的精度往往都是有限的,单精度的浮点数使用 32 位表示,而双精度的浮点数使用 64 位表示;
  • 数学中的小数系统可以通过引入无限序列 ... 可以任意的实数4

在数学上我们总有办法通过额外的符号表示更复杂的数字,但是从工程的角度来看,表示无限精度的数字是不经济的,我们期望通过更小和更快的系统表示范围更大和精度更高的实数。浮点数系统是在工程上面做的权衡,IEEE 754 就是在 1985 年建立的浮点数计算标准,它定义了浮点数的算术格式、交换格式、舍入规则、操作和异常处理5。讨论浮点数也无法脱离该标准,为了回答今天的问题,我们将从以下的两个角度触发:

  • 二进制无法在有限地长度中精确地表示十进制中 0.1 和 0.2;
  • 单精度浮点数、双精度浮点数的位数决定了它们能够表示的精度上限;

二进制与十进制

我们日常生活中使用的数字基本都是 10 进制的,然而计算机使用二进制的 0 和 1 表示整数和小数,所有有限的十进制整数都可以无损的转换成有限长度的二进制数字,但是要在二进制的计算机中表示十进制的小数相对就很麻烦了,我们以 0.375 为例介绍它在二进制下的表示:

小数点后面的位数依次表示十进制中的 0.5、0.25、0.125 和 0.0625 等等,这个表示方法非常好理解,每一位都是前一位的一半。0.375 在二进制表示看来确实是『整数』。然而如下图所示,想要使用二进制表示十进制中的 0.1 和 0.2 是比较复杂的:

6472a0cd1e0ba98e6ec9cb4fa8caf87b.png
decimals-binary-representation

图 2 - 二进制表示的十进制小数

无论是 0.1 还是 0.2,这两个数字都不是二进制中的『整数』,我们没有办法精确地表示它们,只能通过无限循环小数尝试接近它们的真实值;与之相似的是,它们相加的结果 0.3 也无法用有限长度的二进制表示:

6a699337ccef88637c2bfd95ccb0b4b6.png
dot-three-binary-representation

图 3 - 二进制表示的 0.3

这三个不同的数字都会在最后的小数部分无限循环 1100 来趋近于真实值,如果计算机中的浮点数可以表示无限循环小数就有可能解决这个问题,但是事实的真相是浮点数只会表示有限小数,所有超过特定精度的数字都会做舍入处理。

精度上限

编程语言中的浮点数一般都是 32 位的单精度浮点数 float 和 64 位的双精度浮点数 double,部分语言会使用 float32 或者 float64 区分这两种不同精度的浮点数。想要使用有限的位数表示全部的实数是不可能的,不用说无限长度的小数和无理数,因为长度的限制,有限小数在浮点数中都无法精确的表示。

072462590a138a47fd3c51419b0c28fe.png
float-and-double

图 4 - 单精度与双精度浮点数

  • 单精度浮点数 float 总共包含 32 位,其中 1 位表示符号、8 位表示指数,最后 23 位表示小数;
  • 双精度浮点数 double 总共包含 64 位,其中 1 位表示符号,11 位表示指数,最后 52 位表示小数;

我们以单精度浮点数 0.15625 为例,介绍该浮点数在计算机二进制中的表示方法,如下图所示,符号位 0 表示该浮点数为正数,中间的 8 位指数总共可以表示 256 个数字,其中从 [0, 126] 表示 [-127, -1],而 [127, 255] 表示 [0, 128],二进制的 01111100 是十进制的 124,表示 2−32−3,最后的 23 位是二进制的小数 0.25:

1a810d91cb9e2487e721ed020675cdf0.png
floating-number-example

图 5 - 0.15625 的单精度浮点数表示

通过上图中的公式 ????×2???×(1+????????) 可以将浮点数的二进制表示转换成十进制的小数。0.15625 虽然还可以用单精度的浮点数精确表示,但是 0.1 和 0.2 只能使用浮点数表示近似的值:

a168571473d8b0c0bb1347f425613965.png
dot-one-dot-two-floating-number

图 6 - 0.1 和 0.2 的单精度浮点数表示

因为 0.2 和 0.1 只是指数稍有不同,所以上图中只展示了 0.1 对应的单精度浮点数,从上图的结果我们可以看出,0.1 和 0.2 在浮点数中只能用近似值来代替,精度十分有限,因为单精度浮点数的小数位为 23,双精度的小数位为 52,同时都隐式地包含首位的 1,所以它们的精度在十进制中分别是   和  位。

因为 0.1 和 0.2 使用单精度浮点数表示的实际值为 0.100000001490116119384765625 和 0.20000000298023223876953125,所以它们在相加后就得到的结果与我们在一开始看到的非常相似:

db3cc3f74d840a0d09467b56227a3fec.png
dot-three-floating-number

图 7 - 0.1 加 0.2 的结果

上图只是使用单精度浮点数表示的数字,如果使用双精度浮点数,最终结果中的 3 和 4 之间会有更多的 0,但是小数出现的顺序是非常相似的。浮点数的运算法则相对来说比较复杂,感兴趣的读者可以自行搜索相关的资料,我们在这里不展开介绍了。

总结

当我们在不同编程语言中看到 0.300000004 或者 0.30000000000000004 时不应该感到惊讶,这其实说明编程语言正确实现了 IEEE 754 标准中描述的浮点数系统,在使用单精度和双精度浮点数时也应该牢记它们只有 7 位和 15 位的有效位数。

在交易系统或者科学计算的场景中,如果需要更高的精度小数,可以使用具有 28 个有效位数的 decimal 或者直接使用分数,不过这些表示方法的开销也随着有效位数的增加而提高,我们应该按照需要选择最合适的方法。重新回到今天的问题 — 0.1 和 0.2 相加不等于 0.3 的原因包括以下两个:

  • 使用二进制表达十进制的小数时,某些数字无法被有限位的二进制小数表示;
  • 单精度和双精度的浮点数只包括 7 位或者 15 位的有效小数位,存储需要无限位表示的小数时只能存储近似值;

浮点数系统的设计是一个比较有趣的工程问题,因为操作系统一般都是 32 位或者 64 位的,浮点数充分利用了 32/64 位的比特,将每一位的作用都发挥到极致,使用最紧凑和简洁的方式实现了尽可能高的精度。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:

  • 有哪些编程语言内置了高精度的浮点数或者小数?
  • 如何实现一个可以精确表示所有实数(包括有理数和无理数)的系统?
661e624f55cf5a322df698fefc07dab9.gif
  • 面试官问:MySQL的自增ID用完了,怎么办?

  • ArrayList插入1000w条数据之后,我怀疑了jvm...

  • 蚂蚁二面,面试官问我零拷贝的实现原理,当场懵了…

9cb94f5d9c01ed0888309c38800cf9ca.png

明天见(。・ω・。)ノ♡
WRovo
关注 关注
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
floating_point_adder.zip_floating_floating point adder_vhdl 浮点_浮
09-24
该代码描述了一个浮点加法器的功能,浮点格式采用IEEE标准
fpu.tar.gz_FPU 运算_VHDL floating_floating point vhdl_fpu_浮点运算
09-14
浮点运算部件的硬件设计,已经经过测试,可以提高设计效率.
为什么 0.1 + 0.2 = 0.300000004
程序IT圈
10-03 254
JavaScript 作为一门诞生自上个世纪 90 年代的编程语言[^1],从诞生之初就因为诡异的隐式类型转换等原因被黑,很多 JavaScript 的开发者还会吐槽浮点数加法的『奇葩』...
面试官:为什么 0.1 + 0.2 == 0.300000004
热门推荐
小林coding
04-21 2万+
我们在 JavaScript 里执行 0.1 + 0.2,会得到下面这个结果: 那今天,我们来思考几个问题: 为什么负数要用补码表示? 十进制小数怎么转成二进制? 计算机是怎么存小数的? 0.1 + 0.2 == 0.3 吗? … 别看这些问题都看似简单,但是其实还是有点东西的这些问题。 为什么负数要用补码表示? 十进制转换二进制的方法相信大家都熟能生巧了,如果你说你还不知道,我觉得你还是太谦虚,可能你只是忘记了,即使你真的忘记了,不怕,贴心的小林在和你一起回忆一下。 十进制数转二进制采用的是除 2
为什么0.1+0.2=0.30000000000000004
weixin_30730151的博客
01-20 647
文章讨论了计算机中的浮点运算问题,给出了各种不同语言的浮点输出。 浮点数运算 你使用的语言并不烂,它能够做浮点数运算。计算机天生只能存储整数,因此它需要某种方法来表示小数。这种表示方式会带来某种程度的误差。这就是为什么往往0.1 + 0.2 不等于 0.3。 为什么会这样? 实际上很简单。对于十进制数值系统(就是我们现实中使用的),它只能表示以进制数的质因子为分母的分数。1...
valid floating point value什么意思_TFLOPS啥意思 性能对比这样看才靠谱
weixin_39850152的博客
12-05 449
RTX 30显卡的在线发布会上有一个细节特别引人瞩目,那就是公布了一个名为TFLOPS的数据时,如果大家收看的视频有弹幕,一定马上就会弹幕爆炸了。这个参数到底是啥?为什么让大家那么关注呢?咱们今天就来说说吧。TFLOPS是Tera和Floating-point operations per second词组的组合,后者的意思是每秒浮点运算次数,Tera则是万亿的意思,合起来就是每秒浮点运算多少万亿...
valid floating point value什么意思_【每日一算法】什么是二分图?
weixin_39586825的博客
12-01 328
微信改版,加星标不迷路!每日一算法-判断二分图作者:阿广阅读目录1 题目2 解析1 题目给定一个无向图graph,当这个图为二分图时返回true。如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到...
Fixed-point-and-floating-point.rar_dsp_floating_floating point D
09-19
主要是DSP嵌入式开发的基础定点运算和浮点运算的讲解。
fpu.rar_VHDL floating_floating_floating point_浮点_浮点数 运算
09-23
使用VHDL语言描述的单精度浮点处理器。源代码来自国外网站。可实现单精度浮点数的加减乘运算。
f.rar_add floating vhdl_floating_floating point unit_fpu single
09-22
This documents describes a free single precision floating point unit. This floating point unit can perform add, subtract, multiply, divide, integer to floating point and floating point to integer ...
深度剖析0.1 +0.2===0.30000000000000004的原因
weixin_34332905的博客
11-08 297
用一句话概括就是:EcmaScrpt规范定义Number的类型遵循了IEEE754-2008中的64位浮点数规则定义的小数后的有效位数至多为52位导致计算出现精度丢失问题! 如果你看不懂这句话,仔细阅读本篇博客就对了! 首先看下10进制转换为2进制的方法。 数字逻辑电路上的算法是 (0.1)10 = (0.0)2。 吐槽一句,大二的专...
valid floating point value什么意思_为什么需要演讲 想做好演讲 你可能需要这些技巧...
weixin_39617497的博客
12-01 307
人生是需要不断学习的过程,在一次学习关于“演讲”的课程中,我发现了非常有意思的技巧。学习陶峻老师课程这个有意思的技巧是什么呢?陶峻大师(演讲教练)一堂小课堂中用两分钟的教法,告诉我们一个非常有用的学习模型:PEEP,即观点(Point)、解释(Explanation)、例子(Example)、观点(Point)。是不是很有趣,如果你像我一样马上实践尝试,你会发现这个学习模型已经记忆在你的脑海中,形...
PHP7下的协程实现
weixin_33997389的博客
12-16 209
前言 相信大家都听说过『协程』这个概念吧。 但是有些同学对这个概念似懂非懂,不知道怎么实现,怎么用,用在哪,甚至有些人认为yield就是协程! 我始终相信,如果你无法准确地表达出一个知识点的话,我可以认为你就是不懂。 如果你之前了解过利用PHP实现协程的话,你肯定看过鸟哥的那篇文章:在PHP中使用协程实现多任务调度| 风雪之隅 鸟哥这篇...
valid floating point value什么意思_你知道PHP协程是什么吗?
weixin_39714113的博客
12-08 217
什么是协程先搞清楚,什么是协程。你可能已经听过『进程』和『线程』这两个概念。进程就是二进制可执行文件在计算机内存里的一个运行实例,就好比你的.exe文件是个类,进程就是new出来的那个实例。进程是计算机系统进行资源分配和调度的基本单位(调度单位这里别纠结线程进程的),每个CPU下同一时刻只能处理一个进程。所谓的并行,只不过是看起来并行,CPU事实上在用很快的速度切换不同的进程。进程的切换需要进行系...
0.1+0.2=0.30000000000000004
T_zm_cross的专栏
09-21 693
为什么“0.1+0.2=0.30000000000000004”?首先声明这不是bug,原因在与十进制到二进制的转换导致的精度问题! 其次这几乎出现在很多的编程语言中:C/C++,Java,Javascript中,准确的说:“使用了IEEE 754浮点数格式”来存储浮点类型(float 32,double 64)的任何编程语言都有这个问题!  简要介绍下IEEE 754浮点格式:它用科学记数法
为什么 0.1 + 0.2 = 0.300000004
HollisChuang's Blog
04-13 1565
JavaScript 作为一门诞生自上个世纪 90 年代的编程语言[^1],从诞生之初就因为诡异的隐式类型转换等原因被黑,很多 JavaScript 的开发者还会吐槽浮点数加法的『奇葩...
为什么 0.1+0.2=0.30000000000000004
luoganttcc的博客
06-10 564
0.10.2 是如何表示的? 根据前面的讲解,十进制 0.1 转为二进制小数,得到的是 0.0001100… (重复1100)这样一个循环二进制小数,使用 IEEE754 表示如下图:在浮点数的舍入问题上,IEEE 浮点格式定义了 4 种不同的舍入方式,如下表所示。其中,默认的舍入方法是向偶数舍入,而其他三种可用于计算上界和下界。同样的方法,0.2 用单精度浮点数表示是:0.20000000298023223876953125。所以,0.1 + 0.2 的结果是:0.30000000447034835
为什么“0.1+0.2=0.30000000000000004”?
xjanting的博客
03-28 2154
首先声明这不是bug,原因在与十进制到二进制的转换导致的精度问题!其次这几乎出现在很多的编程语言中:C/C++,Java,Javascript中,准确的说:“使用了IEEE 754浮点数格式”来存储浮点类型(float 32,double 64)的任何编程语言都有这个问题!简要介绍下IEEE 754浮点格式:它用科学记数法以底数为2的小数来表示浮点数。IEEE浮点数(共32位)用1位表示数字符号,
valid floating point value什么意思_每个位置的球员,都在干些什么
weixin_39929961的博客
11-29 276
闲聊一点篮球场上位置的事。1有两个顶级球星在位置划分上一直很模糊——哈登和浓眉。习惯上,我们都把哈登算得分后卫,可你也不好说哈登到底是得分后卫还是控球后卫,毕竟他控球时间比任何球员都长,ESPN也把他放在了PG栏里,但既然哈登是跟保罗搭档后场,那保罗在场时,你也不能说哈登是控卫,保罗是得分后卫对不对?当然了,因为不管最佳阵容还是全明星,后场两个位置都是放在一块选,所以哈登到底是哪个位置也...
<<关于javascript的数学是python教的这件事>>_0.1+0.2
最新发布
09-06
在JavaScript中,由于浮点数计算的特殊性,0.10.2相加并不会得到0.3,而是接近0.30000000000000004。这是由于JavaScript使用IEEE 754标准来表示和计算浮点数,而该标准在进行浮点数计算时会产生舍入误差。这种结果...

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • python拦截广告弹窗_selenium+python处理广告弹窗 85408
  • tkinter label背景透明_Tkinter简明教程 14148
  • iphone控制电脑_如何远程控制苹果 Mac 电脑?屏幕共享怎么样操作? 13749
  • matlab示波器坐标调整,SIMULINK示波器参数设置 12705
  • 双 JK 触发器 74LS112 逻辑功能。真值表_时序逻辑电路设计(一):同步计数器... 11548

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 大话2服务器维护,《大话西游2》3月26日维护公告
  • linux服务器性能阈值,Linux服务器性能监控与分析系统的研究与实现
  • 剑侠情缘手游服务器bug修复,剑侠情缘手游因BUG大回档 摆摊功能依然受影响
2021年148篇
2020年218篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

深圳SEO优化公司乌海网站设计公司龙岩如何制作网站推荐张家口推广网站推荐扬州网站关键词优化多少钱网站设计公司南充网站开发报价黑河百度网站优化排名哪家好赤峰SEO按效果付费价格淮南网站优化排名推荐潮州网站关键词优化推荐忻州网站开发多少钱鹤岗网站推广工具哪家好重庆阿里店铺托管焦作seo网站推广多少钱北京营销型网站建设南通企业网站建设报价本溪seo价格合肥建网站哪家好衢州英文网站建设肇庆营销型网站建设公司鹰潭网站制作公司南昌网络广告推广哪家好开封网站seo优化公司日照网站优化排名公司咸宁关键词按天计费多少钱海北设计网站泰州高端网站设计多少钱郑州百度网站优化排名报价丹东阿里店铺运营报价思茅网站排名优化报价歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化