0.42-0.5+0.08与0.08-0.5+0.42是不完全相等,Why is 0.3 - 0.2 - 0.1 (or similar) not equal to zero?
matlab的老师布置了这么一道作业题:尽管我们知道0.42-0.5+0.08与0.08-0.5+0.42是完全相等的,但在Matlab中,二者却不相等,请说明原因。
我大概是知道这与浮点数精度误差有关系,但是还是不能理解,若有误差,在两边数值及符号都完全相等的情况下。
>> 0.42+(-0.5+0.08)ans =0>> (0.42-0.5)+0.08ans =-1.3878e-17>> single(0.42-0.5)+single(0.08)ans =single0>> double(0.42-0.5)+double(0.08)ans =-1.3878e-17
>> q = quantizer('double');
num2bin(q,0.08)ans ='0011111110110100011110101110000101000111101011100001010001111011'>> q = quantizer('double');
num2bin(q,-0.08)ans ='1011111110110100011110101110000101000111101011100001010001111011'>> q = quantizer('double');
num2bin(q,(0.42-0.5))ans ='1011111110110100011110101110000101000111101011100001010001111100'
参考Why is 0.3 - 0.2 - 0.1 (or similar) not equal to zero?
https://matlab.fandom.com/wiki/FAQ#Why_is_0.3_-0.2-0.1.28or_similar.29_not_equal_to_zero.3F
经常提到的那样,某些浮点数不能完全以二进制形式表示。 这就是为什么您看到很小但不是零的结果的原因。 参见EPS。
区别在于0:0.1:0.4会增加一个非常接近但不完全为0.1的数字,原因如下。 因此,经过几步后,它将关闭,而[0 0.1 0.2 0.3 0.4]则将数字强制为正确的值,无论如何它们都可以准确地表示出来。
a=[0 0.1 0.2 0.3 0.4];b=[0:.1:.4];
as=sprintf('%20.18f\n',a)as =0.000000000000000000 % ==0.100000000000000010 % ==0.200000000000000010 % ==0.299999999999999990 % ~= bs !0.400000000000000020 % ==
bs=sprintf('%20.18f\n',b)bs =0.000000000000000000 % ==0.100000000000000010 % ==0.200000000000000010 % ==0.300000000000000040 % ~= as !0.400000000000000020 % ==
-and-format hex;hd=[a.',b.']hd =0000000000000000 0000000000000000 % ==3fb999999999999a 3fb999999999999a % ==3fc999999999999a 3fc999999999999a % ==3fd3333333333333 3fd3333333333334 % ~= !3fd999999999999a 3fd999999999999a % ==
如果要比较两个浮点数,不建议使用==进行比较。
另一种比较方法是检查要比较的两个数字是否“足够接近”(在彼此的公差值范围内)。 例如
% Instead of a == b% If you have MATLAB release R2015a or later, use:a = 0.3;b = 0.1 + 0.2;tol = 5 * eps(a) % A very small value.areEssentiallyEqual = ismembertol(a, b, tol) % areEssentiallyEqual is a logical (a true or false value).
% Instead of a == b
% with releases R2014b and earlier, use:
a = 0.3;b = 0.1 + 0.2;tol = 5 * eps(a)areEssentiallyEqual = abs(a-b) < tol
% for some small value of tol relative to a and b
您可以在MATLAB之外看到相同的行为。 使用铅笔和纸(或黑板或白板等)计算x = 1/3至所需的小数位数。 但是,小数位数必须是有限的。 现在计算y = 3 * x。 用精确的算术,y恰好是1; 但是,由于x并非正好是三分之一,而是四舍五入到三分之一的近似值,因此y不会正好为1。
参考
有关浮点运算的可读介绍,请参阅1996年Cleve’s Corner的文章:
www.mathworks.com/company/newsletters/news_notes/pdf/Fall96Cleve.pdf
For a readable introduction to floating point arithmetic, look at Cleve's Corner article from 1996: Floating Points (PDF) (http://www.mathworks.com/company/newsletters/news_notes/pdf/Fall96Cleve.pdf)For an official "Answer" by the Mathworks in the Answers forum, read Why-does-mat2str-0-005-90-return-0-0050000000000000001-in-matlabFor more rigorous and detailed information on floating point arithmetic, read the following paper: What Every Computer Scientist Should Know About Floating Point Arithmetic (http://docs.sun.com/source/806-3568/ncg_goldberg.html)Another resource is Technical Note 1108 (http://www.mathworks.com/support/tech-notes/1100/1108.html) on the Support section of The MathWorks website.And yet another is Loren's blog A Glimpse into Floating-Point Accuracy
for 问题
“Cannot determine the exact number of iterations for a loop with range ”
%#codegen
ctr=1;
for A = (y_prev-0.01):0.001:(y_prev+0.01)
% Some Calculations
B(ctr) = %some algebraic expression based on the variable "x"
ctr=ctr+1;
end
temp = (y_prev-0.01):0.001:(y_prev+0.01);
y = max(temp(B == max(B)));
非整数或2的幂(例如1/2)的步长会导致舍入误差,这会导致难以预测确切的迭代次数。
You could, for example, use
for At = -10:10A = y_prev - At/1000;
0.42-0.5+0.08与0.08-0.5+0.42是不完全相等,Why is 0.3 - 0.2 - 0.1 (or similar) not equal to zero?相关推荐
- java1男0女_Java项目中数据库字段和用户页面显示之间的转换,比如性别字段:1显示男,0显示女...
开发项目的过程中,经常会碰到这样的问题:学生信息管理系统中,学生的专业.性别字段,底层数据库中存储的信息和在页面显示的是不同步的.比如:性别字段数据库中1代表男,0代表女,而界面上需要我们显示男或者女 ...
- c语言08,C语言08 -- 指针
// // main.m // C8-指针 // // Created by dllo on 15/7/9. // Copyright (c) 2015年 Gaozi. All rights rese ...
- [导入]silverlight 2.0希伯来语及阿拉伯语的support.zip(344.42 KB)
这个项目提供silverlight 2.0与希伯来语及阿拉伯语的support.including从右到左的支持,统一到右及视觉textwrapping功能. 目前,我们在阿尔法测试阶段silver ...
- c语言中转义字符 0,【填空题】在C语言中,用“\\”开头的字符序列称为转义字符, 转义字符‘\\n’的功能是_____; 转义字符‘\\0’的功能是_____;...
[填空题]在C语言中,用"\\"开头的字符序列称为转义字符, 转义字符'\\n'的功能是_____; 转义字符'\\0'的功能是_____; 更多相关问题 在MGB1420万能磨床 ...
- php表达式ax 2 bx c=0,设a,b,c为互不相等的非零实数,求证:方程ax2+2bx+c=0,bx2+2cx+a=0,cx2+...
二语习得专家克拉申(Krashen)提出要在语言教学中提供比学习者水平稍微高一点的"可理解的语言输入",这一理论称为( ) 147.水准测量中,水准仪的i角对测量结果的影响可用( ...
- 华为鸿蒙2.0智慧屏,官宣!华为车载智慧屏将于10月30日发布,或搭载鸿蒙OS 2.0...
10月27日,华为官方宣布,华为车载智慧屏将于10月30日发布,国行华为 Mate40 系列新品也将一同亮相. 据悉,华为车载智慧屏或搭载华为鸿蒙OS 2.0系统,聚合了华为智能手机的大部分适合汽车移 ...
- python61到08使用说明书_python 08 文件操作
ctrl + s 保存至磁盘 .exe .txt .ppt .jpg 文件格式 open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写 open(filenam ...
- 本周首次公开专利数量最多的主要公司(2022.08.01~2022.08.07日)
数据说明:数据来源专利顾如,会因为数据公开周期等因素造成一定误差,未考虑特殊情况,与任何指标无关,以官方公开数据为准仅供参考. 2022年08月01日 ~2022年08月07日 第一次公开专利并且专利 ...
- opensuse 42.2 mysql_【Linux】Grub模式硬盘安装openSUSE 42.2
首先确保可以进去到grub,grub进入方法有很多,easybcd安装grub启动,或者使用grub4dos,可以参考grub的安装配置.这里建议使用grub4dos. 注意:BIOS中最好禁用acp ...
- parseInt(08)或parseInt(09)转换返回0的解决办法
在javascript中使用parseInt()函数转换成整数时会遇到以下这种情况: 使用parseInt()转换'01'~'07'时可以转换成整数1~7,而转换'08'和'09'时,就会出现转换结果 ...
最新文章
- Typora markdown公式换行等号对齐_【精品软件 第3期】 有颜有料的编辑器——Typora
- Go开发之路 -- 指针类型
- linux pci扫描链表,Linux Kernel ---- PCI Driver 分析
- 数字经济时代凸显网络安全重要性
- 用 Go 语言,做 Web 编程开发
- html文件头自动生成,基于infinispan源码包HtmlGenerator代码生成器通过指定头部、标题、底部等进行生成HTML文件...
- hdu4911 Inversion-归并排序
- 使用Xtend构建Vaadin UI
- 汇编语言——第1次上机实验
- linq to sql 行转列_SQL进阶:SQL高级编程语法实例
- EasyUI 验证框使用方法
- html3d电子相册,3d电子相册制作软件哪个好, 自带翻页电子相册模板,电子相册生成flash等多种格式...
- 红外非均匀矫正matlab实现,一种红外图像非均匀性校正方法与流程
- 数字滤波器及GUI界面的设计(MATLAB)
- 深度学习面试题之LSTM补充
- 随便说说,中国开发人员的不同层次和一些思考。
- CT计算机组成及其特点,浅析CT图像的特点及常用扫描方式
- PM2.5传感器通过树莓派推送到ThingsPanel
- 多线程使用场景及总结
- win10照片查看器_Win10小技巧,帮你事半功倍