浮点运算一直非常玄学。

任何一个学过小数点运算的拥有小学数学水平的人,都应该知道 1.0-0.9=0.1。然而当你把这个问题抛给可以计算出圆周率小数点后上百位、拥有超强算力的计算机的时候,结果总是非常迷。

你会发现,使用double或者float得出的计算结果,总是跟我们的预期有一点点差距,这就使得浮点运算容易让人觉得“不精确”。

实际上,因为我们人类理解的数字是十进制,而计算机理解的数字是二进制。比如101.11这个数字,在人类眼中是一百零一点一一,而在电脑看来则是1 * 2^2 +0 *2^1 + 1*2^0 + 1*2^-1 + 1*2^-2 = 4+0+1+1/2+1/4 = 5.75,这个差距着实有点可怕的。

用二进制来表达十进制的小数点,仿佛在接两根口径不一致的管子,就会出现总是对不上的情况。比如为了表示0.2这个十进制下的数字,二进制只能用 1/(2^n)来表示小数,于是:

0.01 = 1/4 = 0.25 ,太大

0.001 =1/8 = 0.125 , 又太小

0.0011 = 1/8 + 1/16 = 0.1875 , 逼近0.2了

0.00111 = 1/8 + 1/16 + 1/32 = 0.21875 , 又大了

0.001101 = 1/8+ 1/16 + 1/64 = 0.203125 还是大

0.0011001 = 1/8 + 1/16 + 1/128 = 0.1953125 这结果不错

0.00110011 = 1/8+1/16+1/128+1/256 = 0.19921875

……

当然,理论上是可以做到无限逼近的。然而我们的物理存储介质的容量毕竟不是无限扩展的,那么在编程语言中就会采用一些取巧的方式来进行权衡。比如java中规定double是32位,float是64位。但无论是多少位,总之是个博弈的结果,并不能完美的解决上述问题,甚至在不同平台、硬件下,同样的操作、同样的位数,得出的结果都可能不一样,更不用说在不同的编程语言环境下了。

比如0.1+0.2,结果如下:

有人因此建立了一个网站:

https://0.30000000000000004.com/

正是因为浮点运算的精度问题,使得其无法应用在像银行这样对数字极度敏感的场景中。银行使用的是定点计算,简单来说,就是把小数转换为整数的一种计算。因为这样操作,所有的账目都是可以预测的。

但浮点运算可以表示比的范围比整数更大、在大数运算中也更有优势,它天生是为表示超大数或者无限值。因此在类似图神经网络这种注重数量大于精度的场景下,才是浮点运算大显身手的地方。

转自:新智元

- END -

如果看到这里,说明你喜欢这篇文章,请转发、点赞。扫描下方二维码或者微信搜索「perfect_iscas」,添加好友后即可获得10套程序员全栈课程+1000套PPT和简历模板向我私聊「进群」二字即可进入高质量交流群。

扫描二维码进群↓

在看 

浮点运算为什么不准?有人为0.30000000000000004建了个网站相关推荐

  1. python0.1+0.2_为什么0.1+0.2=0.30000000000000004

    语言 代码 结果 C #includeint main(int argc, char* argv) {printf("%.17fn", .1+.2);return 0;} 0.30 ...

  2. JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后

    Brief 一天有个朋友问我"JS中计算0.7 * 180怎么会等于125.99999999998,坑也太多了吧!"那时我猜测是二进制表示数值时发生round-off error所 ...

  3. 一站式快速自助建站-超低价0代码建站套餐助你轻松拥有自己的网站

    简介:一站式快速自助建站-超低价0代码建站套餐助你轻松拥有自己的网站 点击链接,一站式快速自助建站助你轻松拥有自己的网站 https://developer.aliyun.com/plan/activ ...

  4. JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后 1

    Brief 一天有个朋友问我"JS中计算0.7 * 180怎么会等于125.99999999998,坑也太多了吧!"那时我猜测是二进制表示数值时发生round-off error所 ...

  5. 杜绝0.1 + 0.2 =0.30000000000000004

    // 杜绝0.1 + 0.2 =0.30000000000000004 问题:function add(num1, num2) {const num1Digits = (num1.toString() ...

  6. 0基础建站教程,1小时建网站,王通教程

    0基础建站教程,一小时建网站 视频教程 赠王通SEO赚钱秘笈 1.如何购买空间域名 2.如何使用FTP 3.如何1小时做个人博客网站 4.如何1小时做企业展示网站 5.如何1小时做论坛社区网站 6.如 ...

  7. 浮点数的世界 0.1 + 0.2 = 0.30000000000000004?

    文章目录 背景 0.1 + 0.2 的浮点数计算结果 原因 原理 有趣的0.30000000000000004 参考 背景 今天看到一个有趣的新闻,浮点数计算导致的灾难,借此机会再理解一下浮点数的原理 ...

  8. java中3 0.1_为什么java里面3*0.1=0.30000000000000004,而4*0.1=0.4?-Go语言中文社区

    作者:蓝色 链接:https://www.zhihu.com/question/56545018/answer/149620518 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  9. 为什么java里面3*0.1=0.30000000000000004,而4*0.1=0.4?

    作者:蓝色 链接:https://www.zhihu.com/question/56545018/answer/149620518 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

最新文章

  1. JUnit4中使用Hamcrest测试框架的assertThat断言 小实例
  2. Use Cases in an Agile Backlog
  3. 谷歌自锤Attention:纯注意力并没那么有用,Transformer组件很重要
  4. 【转】如何理解c和c++的复杂类型声明
  5. 30分钟学玩转RabbitMQ
  6. 支持自动水平拆分的高性能分布式数据库TDSQL
  7. FusionCharts V3图表导出图片和PDF属性说明
  8. 我的Google Analytics(分析)正式通知升级到新版本
  9. 信息论和贝叶斯(或许会继续补充)
  10. 排错万能金钥匙之Linux系统应用
  11. 89c51 单片机 c语言 编写sszymmh 歌曲 文档,Proteus仿真51单片机生日快乐音乐播放器...
  12. 科技论文写作个人心得
  13. Boost电路实战详解!(高效率同步整流,PID闭环追踪)
  14. js去除字符串中的空白字符(也可以去除其他字符串)
  15. 记录卸载h5py出现的问题
  16. groupby后选取列和不选取列的区别
  17. C#中的Action是什么意思
  18. 千寻魔方MC180M——厘米/分米级高精度定位
  19. vue中使用xlsx导出Excel 并设置样式,解决未完全合并单元格框线的BUG
  20. 用于脉冲检测的三种检波电路

热门文章

  1. 【ACM】 multiset 的 一些应用
  2. 老码农90%的程序猿都是瞎努力,这份路线教你成为高手!
  3. 如何用Jupyter Notebook制作新冠病毒疫情追踪器?
  4. 速度提升270倍!微软和浙大联合推出全新语音合成系统FastSpeech
  5. 忽略这一点,人工智能变人工智障!
  6. 技术大佬们都推荐的vim学习指南来了,值得收藏!
  7. 上映 10 天,票房就突破 10 亿的《海王》真的有那么好看?
  8. 今晚8点免费直播 | 详解知识图谱关键技术与应用案例
  9. “照骗”难逃Adobe的火眼金睛——用机器学习让P图无所遁形
  10. AI一分钟 | 厉害了!英特尔正式发布电动飞行汽车;贝佐斯笑了,多家PC厂商结盟亚马逊Alexa,直怼微软Cortana