计算误差——ACM计算几何中的精度问题
- 浮点数为何会有精度问题
| 占字节数 | 数值范围 | 十进制精度位数 | |
| float | 4 | -3.4e-38~3.4e38 | 6~7 |
| double | 8 | -1.7e-308~1.7e308 | 14~15 |
如果内存不是很紧张或者精度要求不是很低,一般选用double。14位的精度(是有效数字位,不是小数点后的位数)通常够用了。注意,问题来了,数据精度位数达到了14位,但有些浮点运算的结果精度并达不到这么高,可能准确的结果只有10~12位左右。那低几位呢?自然就是不可预料的数字了。这给我们带来这样的问题:即使是理论上相同的值,由于是经过不同的运算过程得到的,他们在低几位有可能(一般来说都是)是不同的。这种现象看似没太大的影响,却会一种运算产生致命的影响: ==。恩,就是判断相等。注意,C/C++中浮点数的==需要完全一样才能返回true。来看下面这个例子:
#include <iostream>
#include<math.h>
using namespace std;
int main()
{
double a=asin(sqrt(2.0)/2)*4.0;
double b=acos(-1.0);
printf("a =%.20lf\n",a);
printf("b =%.20lf\n",b);
printf("a-b=%.20lf\n",a-b);
printf("a==b = %d\n",a==b);
return 0;
}
解决办法,引进eps,辅助判断浮点数相等
- eps(epsilon)
eps最常见的取值是1e-8左右。引入eps后我们判断两浮点数a,b相等的方式是:
定义三出口函数:int sgn(double a){ return a< -eps?-1:a< eps?0:1;}
则各种判断大小的运算都应做如下修改:
| 传统意义 | 修正写法1 | 修正写法2 |
| a==b | sgn(a-b) ==0 | fabs(a -b) <eps |
| a!=b | sgn(a-b) !=0 | fabs(a-b)>eps |
| a<b | sgn(a-b)<0 | a-b<-eps |
| a<=b | sgn(a-b)<=0 | a-b<eps |
| a>b | sgn(a-b)>0 | a-b>eps |
| a>=b | sgn(a-b)>=0 | a-b>-eps |
这样才能把相差非常近的浮点数判为相等,相差较大的数判为不等。
ps:养成好习惯,尽量不要对浮点数用==判断。修正写法2中就没有等号
计算误差——ACM计算几何中的精度问题的更多相关文章
- ACM 计算几何中的精度问题(转)
http://www.cnblogs.com/acsmile/archive/2011/05/09/2040918.html 计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模 ...
- ACM计算几何题目推荐
//第一期 计算几何题的特点与做题要领: 1.大部分不会很难,少部分题目思路很巧妙 2.做计算几何题目,模板很重要,模板必须高度可靠. 3.要注意代码的组织,因为计算几何的题目很容易上两百行代码,里面 ...
- 关于JavaScript中计算精度丢失的问题
摘要: 由于计算机是用二进制来存储和处理数字,不能精确表示浮点数,而JavaScript中没有相应的封装类来处理浮点数运算,直接计算会导致运算精度丢失. 为了避免产生精度差异,把需要计算的数字升级(乘 ...
- 计算价格, java中浮点数精度丢失的解决方案
计算价格, java中浮点数精度丢失的解决方案
- 【ZOJ】3785 What day is that day? ——浅谈KMP在ACM竞赛中的暴力打表找规律中的应用
转载请声明出处:http://www.cnblogs.com/kevince/p/3887827.html ——By Kevince 首先声明一下,这里的规律指的是循环,即找到最小循环周期. 这 ...
- entityFramework 中decimal精度缺失问题
在entityFramework中,decimal精度默认为2位数,当要设置的精度大于2位并且数据库中设置的decimal精度大于2位时,则将数据保存在数据库中后两位的小数内容将强制为00 解决方案: ...
- Python中浮点数精度处理
Python中,浮点数运算,经常会碰到如下情况: 出现上面的情况,主要还是因浮点数在计算机中实际是以二进制保存的,有些数不精确.比如说: 0.1是十进制,转化为二进制后它是个无限循环的数:0.0001 ...
- JS中浮点数精度误差解决
问题出现 0.1 + 0.2 = 0.30000000000000004 问题分析 对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封 ...
- linux中时间精度的获取问题【转】
转自:http://www.xuebuyuan.com/877633.html 目前项目需要,需要对时间进行基准,基准的精度在微秒.下午老刘给我说不能用do_gettimeofday因为他的精度虽然可 ...
随机推荐
- MySQL Workbench基本操作
MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具.它是著名的数据库设计工具DBDesigner4的继任者.你可以用MySQL Workbench设计和创建新的数据库图示,建 ...
- 文件I/O和标准I/O
转载:https://blog.csdn.net/kyang_823/article/details/79496561 一.文件I/O和标准I/O文件I/O:文件I/O也称为不带缓冲的I/O(unbu ...
- 有用的 SystemTap 脚本
https://segmentfault.com/a/1190000000680628 https://github.com/posulliv/stap
- 在 IIS 中承载 WCF 服务
本主题概述了创建 Internet 信息服务 (IIS) 中承载的 Windows Communication Foundation (WCF) 服务所需的基本步骤. 本主题假设您熟悉 IIS 且了解 ...
- WIN10中使用Hyper-V 配置虚拟机宿主机互ping
在Windows10 Hyper-V 中安装 Linux (Ubuntu16.04)虚拟机无法 ping 通宿主机,宿主机可以ping通虚拟机. 这种情况下关闭 Windows 防火墙就能ping通 ...
- sqlite自己主动更新数据库
写一个类继承自 SQLiteOpenHelper 系统会自己主动加入构造方法. onCreate方法.onUpgrade方法 当数据库里面数据或者表结构有所修改时.咱们须要升级数据库 这个时候.版本 ...
- Thinkphp中使用PHPmailer发送邮件
在ThinkPHP\Extend\Vendor\目录下放入PHPMailer文件夹,里面包含以下文件 重置密码发送邮件 public function recover(){ if($this-> ...
- JavaScript基础 -- js常用内置方法和对象
JS中常用的内置函数如下: 1.eval(str):计算表达式的结果. 2.parseInt(str,n):将符串转换成整数数字形式(可指定几进制). 3.parseFloat(str):将字符串转换 ...
- python库学习笔记——re库:正则表达式入门(一)
什么是正则表达式? 我们在处理文本文件的时候,会按照某种规则查找某些特定的字符串.比方我们希望从一堆电子档案中找到人员的电话号码整理成通讯录.于是,我们可以利用特定字符串的规律编程获得我们想要的信息. ...
- 【Beijing WC2012】 冻结
[题目链接] 点击打开链接 [算法] dist[i][j]表示到达i号城市,使用了j次魔法,所用时间的最小值 那么,dist[i][j]可以转移到dist[k][j+1]和dist[k][j],一边s ...