刚刚在逛Stack的时候,看见有人在问Java下的一个浮点数运算的问题,这个问题我之前也碰到过,不过项目中遇见的比较少,就忘记了。想想还是做个笔记,记录一下,以供后续温习。

有趣的小例子

  先做一道算术题0.1+0.2=?,也许你想都不用想就回答等于0.3,那么在计算机中是如何表现的呢?测试如下:

var a = 0.1 + 0.2;
var b = 0.3;
Console.WriteLine(a);
Console.WriteLine(a == b);

输出结果是:0.3和False,0.3!=0.3?且不说为什么,再测试一段:

float a = 0.7f;
float b = 0.6f;
Console.WriteLine(a - b);

输出结果是:0.09999996,不等于0.1,我的机器抽风了?再试试:

float a = 0.75f;
float b = 0.25f;
Console.WriteLine(a - b);

输出结果是:0.5,居然又正常了,顿时对C#有了一股深深的怨念,这点小事儿你都办不好,不过想想那些大神的能力肯定甩我几十条街,不会犯这种低级错误,还是看看为什么吧。

分析

  究其根本,还是因为计算机采用二进制来表示十进制数据,C#中采用IEEE754标准来存储浮点格式,单精度的浮点格式分为1位符号位、8位偏置指数位、23位小数位,通常,我们将十进制转换为二进制需要进行如下操作:

  将浮点型数据分为整数部分和小数部分,整数部分除2取余,得到的商再除以2取余,直到商等于0为止,然后把得到余数反序排列,就得到了整数部分;小数部分用乘2法不断将整数部分取出,知道小数中的部分为0或者达到精度时为止。以4.25为例:

  整数位:4

  4/2=2                  0

  2/2=1                  0

  1/2=0                  1

  将001反序得到100即整数位4

  小数位:0.25

  0.25*2=0.5          0

  0.5*2=1.0            1

  01即表示0.25

可是当小数位为0.6时,推算如下:

  0.6*2=1.2            1

  0.2*2=0.4            0

  0.4*2=0.8            0

  0.8*2=1.6            1

  0.6*2=1.2            1

  0.2*2=0.4            0

  0.4*2=0.8            0

  0.8*2=1.6            1

  ......

如此循环往复,很明显23位是无法完全表述0.6这个小数的,这也就导致了上诉异常的产生。

  .NET中提供了decimal来解决这个问题,但decimal也是浮点数类型,只是精度更高,仍然有精度损失存在,所以,浮点数运算是一件非常危险的事情,还请慎重。

转载于:https://www.cnblogs.com/krockey/p/5803152.html

0.1+0.2==0.3?相关推荐

  1. Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项(转)

    Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项 参考:https://blog.csdn.net/weixin_40475396/article/detail ...

  2. mysql 8.0 docker_Docker安装MySQL8.0的实现方法

    环境:MacOS_Cetalina_10.15.1.Mysql8.0.18.Docker_2.0.0.3 1.docker仓库搜索mysql docker search mysql 2.docker仓 ...

  3. RedHat 7.0及CentOS 7.0禁止Ping的三种方法

    作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=538 前言: "Ping"属于ICMP协议(即"Internet控制报文协议") ...

  4. 【Linux】在VirtualBox-6.0中安装Manjaro18.0

    1.参考博客: VMware虚拟机下Manjaro17.1.6安装详细教程 2.在VirtualBox-6.0中安装Manjaro18.0 1)基本步骤和博客中安装17.1.6相同,下面只记录不同的. ...

  5. 编译可在Nexus5上运行的CyanogenMod13.0 ROM(基于Android6.0)

    编译可在Nexus5上运行的CyanogenMod13.0 ROM (基于Android6.0) 作者:寻禹@阿里聚安全 前言 下文中无特殊说明时CM代表CyanogenMod的缩写. 下文中说的&q ...

  6. 从零开始学习tensorflow2.0之熟悉tf2.0的数据

    导入tensorflow2.0 安装tensorflow2.0,使用pip安装,在jupyter notebook之中 !pip install tensorflow !pip install ten ...

  7. 记selenium1.0升级到selenium2.0

    前阵子因为要进行支持多浏览器的自动化测试,原来selenium1.0仅支持到firefox3.6,IE8,chrome4的版本,而公司GA数据显示用户多使用IE9,Firefox20,chrome26 ...

  8. 更改mvc版本的时候,手动修改交3.0改到4.0,将razor改到2.0,仍然提示出现错误,mvc3.0...

    偶然碰到,更改mvc版本,由3.0升级到4.0,但是依然提示3.0的错误 几经周折排查,最终发现 <runtime><assemblyBinding xmlns="urn: ...

  9. oracle websp,探索Web2.0成就SP 2.0之路

    最近我看到互联网上最火爆的话题是:Web2.0如何赢利?而在SP行业论坛中最热的讨论是:是SP如何走出当前的困局,最近也有些行业人士抛出了一个SP2.0的概念.前段时间和网易前内容总监李学凌聊天,他说 ...

  10. torch==1.1.0和torchvision-0.3.0安装

    torch==1.1.0和torchvision-0.3.0安装 分开安装,每次都会把torch升级成1.5.0把版本.解决办法,一起安装. pip3 install --timeout=12000 ...

最新文章

  1. microsoft project 出现不能保存为xls文件时可以按照如下方法解决
  2. android飞翔的小鸟游戏素材包_开心消消乐×愤怒的小鸟:为开心而战
  3. 牛客题霸 [输出二叉树的右视图] C++题解/答案
  4. 详解Class类文件的结构(上)
  5. 天大c语言离线考核答案,【天大考核】2019年秋学期考试《公共关系学》离线作业考核试题答案100分...
  6. oracle基本的操作命令,oracle命令基本操作
  7. 【M1兼容】阿里云盘小白羊版 Mac版(支持满速)
  8. 狗和披萨:使用TensorFlow.js在浏览器中实现计算机视觉
  9. 极客学院腾讯 TAPD·极客开放日 [敏捷开发畅想与实战]
  10. 群体智能之粒子群优化(PSO)
  11. 关于Boost的Asio的信号灯超时时间已到错误
  12. R数据分析:列线图的做法及解释
  13. 干货:中国移动互联网行业深度报告
  14. 运营实战:5个步骤分析目标人群画像流程图
  15. C#也能做机器学习?基于.NET的AI智能应用市场还是一片“处女地”
  16. python中else是指什么意思_python中elif什么意思?
  17. java http请求发送unicode_c++ 使用httpclient获取网页及utf8与unicode之间转码
  18. Ubuntu中给手机安装apk文件
  19. 导数与梯度,切线和法向量
  20. 高清画质,语音降噪,简单易用-QVE屏幕录制

热门文章

  1. Mssql 之 定期备份数据库
  2. 操作系统中的进程与线程
  3. CentOS 5.5 挂载windows ntfs 文件系统
  4. 【连载】【FPGA黑金开发板】Verilog HDL那些事儿--12864(ST7565P)液晶驱动(十三)...
  5. (DML触发器)如何正确理解触发器的deleted表和inserted表(转)
  6. 基于ArcSDE的影像数据管理-疑惑篇 (转载)
  7. 几种常用平衡树的概述(持续更新]
  8. Oracle EXP-00091解决方法
  9. nanomsg(ZeroMQ with C)
  10. POJ 3691 DNA repair AC自动机 + DP