ACM计算几何中的精度问题(转)

详解浮点数的精度问题 详解浮点数精度问题 阅读详情

计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,简直“画龙点睛”。这些年的题目基本是朝着越来越不卡精度的方向发展了,但是也不乏一些%^&%题#$%$^,另外有些常识不管题目卡不卡,都是应该知道的。今天我就开膛回顾下见过且还有印象的精度问题,由于本人见识和记忆均有限,望各位大神瞄过后不吝补充。另外,为了弥补我匮乏的文思,我可能乱扯些不太相关或者尽人皆知的东西凑数。那么,现在开始。

计算几何的精度问题说到底其实是浮点数的精度问题,但我觉得“计算几何”比“浮点数”更能吸引眼球,所以选了这个标题。

1.浮点数为啥会有精度问题:

浮点数(以C/C++为准),一般用的较多的是float, double。

 

占字节数

数值范围

十进制精度位数

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<stdio.h>

#include<math.h>

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;

}

输出:

      a = 3.14159265358979360000

      b = 3.14159265358979310000

 a - b = 0.00000000000000044409

a == b = 0

我们解决的办法是引进eps,来辅助判断浮点数的相等。

2. 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

这样,我们才能把相差非常近的浮点数判为相等;同时把确实相差较大(差值大于eps)的数判为不相等。

PS: 养成好习惯,尽量不要再对浮点数做==判断。例如,我的修正写法2里就没有出现==。

3. eps带来的函数越界

如果sqrt(a), asin(a), acos(a) 中的a是你自己算出来并传进来的,那就得小心了。

如果a本来应该是0的,由于浮点误差,可能实际是一个绝对值很小的负数(比如1e-12),这样sqrt(a)应得0的,直接因a不在定义域而出错。

类似地,如果a本来应该是±1,则asin(a)、acos(a)也有可能出错。

因此,对于此种函数,必需事先对a进行校正。

4. 输出陷阱I

这一节和下一节一样,都是因为题目要求输出浮点数,导致的问题。而且都和四舍五入有关。

说到四舍五入,就再扯一下相关内容,据我所知有三种常见的方法:

1. printf(“%.3lf”, a);  //保留a的三位小数,按照第四位四舍五入

2. (int)a;  //将a靠进0取整

3. ceil(a); floor(a);   //顾名思义,向上取证、向下取整。需要注意的是,这两个函数都返回double,而非int

其中第一种很常见于输出(nonsense…)。

现在考虑一种情况,题目要求输出保留两位小数。有个case的正确答案的精确值是0.005,按理应该输出0.01,但你的结果可能是0.005000000001(恭喜),也有可能是0.004999999999(悲剧),如果按照printf(“%.2lf”, a)输出,那你的遭遇将和括号里的字相同。

解决办法是,如果a为正,则输出a+eps, 否则输出a-eps

典型案例: POJ2826

5. 输出陷阱II

ICPC题目输出有个不成文的规定(有时也成文),不要输出: -0.000

那我们首先要弄清,什么时候按printf(“%.3lf\n”, a)输出会出现这个结果。

直接给出结果好了:a∈(-0.000499999……, -0.000……1)

所以,如果你发现a落在这个范围内,请直接输出0.000。更保险的做法是用sprintf直接判断输出结果是不是-0.000再予处理。

典型案例:UVA746

6. 范围越界

这个严格来说不属于精度范畴了,不过凑数还是可以的。请注意,虽然double可以表示的数的范围很大,却不是不穷大,上面说过最大是1e308。所以有些时候你得小心了,比如做连乘的时候,必要的时候要换成对数的和。

典型案例:HDU3558

7. 关于set<T>

有时候我们可能会有这种需求,对浮点数进行 插入、查询是否插入过 的操作。手写hash表是一个方法(hash函数一样要小心设计),但set不是更方便吗。但set好像是按==来判重的呀?貌似行不通呢。经观察,set不是通过==来判断相等的,是通过<来进行的,具体说来,只要a<b 和 b<a 都不成立,就认为a和b相等,可以发现,

如果将小于定义成:      bool operator < (const Dat dat)const{return val < dat.val - eps;}就可以解决问题了。 (基本类型不能重载运算符,所以封装了下)

8. 输入值波动过大

这种情况不常见,不过可以帮助你更熟悉eps。假如一道题输入说,给一个浮点数a, 1e-20 < a < 1e20。那你还敢用1e-8做eps么?合理的做法是把eps按照输入规模缩放到合适大小。

典型案例: HUSTOJ 1361

9. 一些建议

容易产生较大浮点误差的函数有asin、 acos。欢迎尽量使用atan2。

另外,如果数据明确说明是整数,而且范围不大的话,使用int或者long long代替double都是极佳选择,因为就不存在浮点误差了(尽管我几乎从来都只用double --!)

ACM计算几何篇 1 前言 1.1 计算几何算法 1.2 计算几何题目特点及要领 1.3 预备知识 2 凸包 2.1 定义 2.1.1 凸多边形 2.1.2 凸包 2.2 颜料配色问题 2.2.1 问题描述 2.2.2 问题简化 2.2.3 问题抽象 2.2.4 数学抽象 2.2.4.1 Convex Combination And Affine Combination 2.2.4.2 区别与联系 ... 阅读详情

相关推荐

ACM计算几何题目推荐

把下面的东东都看看,题目刷刷应该就差不多了吧哈。。哈哈。。 其实也谈不上推荐,只是自己做过的题目而已,甚至有的题目尚未AC,让在挣扎中。之所以推荐计算几何题,是因为,本人感觉ACM各种算法中计算几何算是比较实际的算法,在很多领域有着重要的用途(例如本人的专业,GIS)。以后若有机会,我会补充、完善这个列表。 计算几何题的特点与做题要领: 1.大部分不会很难,少部分题目思路

智障 5960

计算几何中的精度问题(转)

计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,简直“画龙点睛”。这些年的题目基本是朝着越来越不卡精度的方向发展了,但是也不乏一些%^&%题#$%$^,另外有些常识不管题目卡不卡,都是应该知道的。今天我就开膛回顾下见过且还有印象的精度问题,由于本人见识和记忆均有限,望各位大神瞄过后不吝...

weixin_30765577的博客 540

ACM几何基础篇

1 前言 1.1 生产生活 1.2 ICPC竞赛 2 准备知识 2.1 头文件及函数及常量 2.2 浮点误差 2.2.1 计算误差 2.2.2 判等 2.2.2.1 解决方案 1 误差判别法 2.2.2.2 解决方案 2 化浮为整 2.2.3 负零 2.2.4 反三角函数 2.3 模板总结 3 点与向量 3.2 相关定义 3.1.1 点的定义 3.1.2 向量的定义 3.2...

林夕 6881

关于float浮点数计算精度问题的深入分析

在Java中,或者说在任何一门语言中,float和double两种类型浮点数计算的精度问题都是老生常谈了。在进行跟钱相关的计算时(毕竟是白花花的银子)的时候如果不注意这两种浮点类型往往会出现许多莫名其妙的bug且难以排查,所以我们不管见到什么一股脑全用BigDecimal算了,也是一种你好我好大家好的万金油方案。但是为什么会有浮点数误差?Java中float有效位数为7位为什么却连0.1都存不了?...

半斤米粉闯天下的博客 9797

习题6-3 使用函数输出指定范围内的完数

其中函数factorsum须返回int number的因子和;函数PrintPN要逐行输出给定范围[mn]内每个完数的因子累加形式的分解式,每个完数占一行,格式为“完数 = 因子1 + 因子2 + ... + 因子k”,其中完数和因子均按递增顺序给出。如果给定区间内没有完数,则输出一行“No perfect number”。

cutto的博客 862

永磁同步电机高效标定技术:从理论到实践的全面解析

本文全面解析永磁同步电机高效标定技术,从MTPA标定、弱磁区优化到初始角校准,详细介绍了理论原理和实战技巧。针对新能源汽车应用场景,提供标定系统集成要点和AI辅助优化方案,帮助工程师提升电机性能标定效率与精度。

weixin_28452161的博客 501

浮点数的表示和精度

double的尾数是52bit,高于32bit的int,所以用dobule表示int不会有精度损失。matlab内部采用double,1+1/2^53对double来说就是1,所以1+1/2^53不会大于1。从表中可以看到,double内部表示的设计是很有规律的,按照对应64位数的顺序依次为 +0、正非规范数、正规范数、正无穷大、符号位为正的NaN、-0、负非规范数、负规范数、负无穷大、符号位为负的NaN。都是 1.xxxxxx * 2^e 表示的,这个 xxxxx 就是底数,1 是省略不写的。

木牛的博客 6219

2.6 SST的核心性能指标体系

本文构建了固态变压器(SST)的核心性能指标体系,涵盖电气性能、可靠性、经济性和环境适配性四大类指标。电气性能指标包括运行效率(≥97%)、功率密度(≥900kVA/m³)、谐波畸变率(≤3%)等关键参数;可靠性指标设定MTBF≥43800h、年均故障率≤1.2次/年等标准;经济性指标对比分析了初始购置成本(45-55万元)和全生命周期成本(48-55万元);环境适配性指标则明确了温度、海拔等工况要求。该体系采用量化公式和国标限值,为SST的性能测试、选型和优化提供了统一标准。

技术工作者 597

C语言小白——变量和常量

@[TOC]C语言自学——数据的表现形式及其运算 #一.变量和常量 1.常量:在程序运行过程中,其值不能被改变的量成为常量。 &amp;amp;lt;1&amp;amp;gt;.整型常量 100, 0.1, 0, -234等都是整型常量。 &amp;amp;lt;2&amp;amp;gt;.实型常量 ①十进制小数形式,由数字和小数点组成。如:123.123, 0.323, -56, 13.0等。 ②指数形式,如12.34e3(代表12.3410∧3),-32.

axiaochongzhi的博客 563

Simulink中通过MEX与MinGW实现C/C++结构体变量的高效导入

本文详细介绍了在Simulink中通过MEX工具链与MinGW编译器,高效导入C/C++结构体变量的完整流程。文章从需求背景出发,逐步讲解了MinGW环境配置、.h文件编写规范、核心导入命令Simulink.importExternalCTypes的使用,以及如何在MATLAB Function模块和总线创建器中调用自定义结构体,旨在实现模型与代码的无缝对齐,为后续仿真和代码生成奠定坚实基础。

weixin_29056781的博客 341

图形学基础知识:着色(三)Rendering Pipeline与Shader

管线(Pipeline) 什么是管线? 管线我们可以理解为流水线,流水线大家都懂,就是工厂里面生产东西的一整套流程。例如饮料厂要生产饮料,需要洗瓶子,倒饮料,加盖,包装等等,这一整套过程就是流水线。那么我们要把一个三维场景渲染成一幅二维的图像,同样需要一个先干嘛再干嘛然后干嘛最后干嘛的过程,这个过程或流水线,我们就称之为管线。 实时渲染管线(Real-time Rendering Pipeline) 通过前面几篇的学习,我们知道了要把一个三维场景渲染成一幅二维的图像大致分为以下几个步骤: M.

王王王渣渣的博客 2532

ACM 计算几何中的精度问题(转)

计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,简直“画龙点睛”。这些年的题目基本是朝着越来越不卡精度的方向发展了,但是也不乏一些%^&%题#$%$^,另外有些常识不管题目卡不卡,都是应该知道的。今天我就开膛回顾下见过且还有印象的精度问题,由于本人见识和记忆均有限,望各位大神瞄过后不吝补充。另

MyHeaven7的博客 517

QT Android开发之Android端usb调试模式设置与问题解决

QT Android开发之Android端usb调试模式设置与问题解决 一.QT android开发android端usb调试模式设置 QT android开发环境搭建完成后,android设备需要打开usb调试模式才能正常连接,下面以小米ipad为例进行设置(其他手机和ipad设置方法类似) 二.小米ipad打开usb调试模式 1.设置----我的设备-----全部参数信息-----OS版本---点击这里6次以上就进入开发者模式。

热土程序园,利他愉己~ 1127

[转] 计算几何中的精度问题

计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,简直“画龙点睛”。这些年的题目基本是朝着越来越不卡精度的方向发展了,但是也不乏一些%^&%题#$%$^,另外有些常识不管题目卡不卡,都是应该知道的。今天我就开膛回顾下见过且还有印象的精度问题,由于本人见识和记忆均有限,望各位大神...

bancaidun1539的博客 178

OpenCV实战之人脸美颜美型(八)——大眼(下)

我们需要将上述描述量化表达,以r代表上述变形区域的圆的半径,X表示原始图像像素到变形圆圆心的距离,Y表示像素变形后的其距离变形圆圆心的距离,则其形状大致如下图所示。如下图所示,我们可以规定处理区域为眼睛为圆心的一个圆形,从圆心区域开始图像会放大,但该放大的比例随着距离圆心的距离而变小,直至边缘区域的放大比例为0。不过在实际图像变形操作中我们要从目标图像映射到原图,因此我们需要将X/Y调换,让X表示变形后图像的像素距离变形圆中心的距离,Y表示原图像素距离变形圆中心的距离,则其形状如下图所示。

On my way 901

73、结合无人机进行rk3588oak-lite跟踪目标物体进行识别、跟踪

搭建仿真转换模型环境,主要python版本和我下载的rknn2的版本。截取shape节点,输出模型。so库也要对应转模型的whl。其中安装的whl版本。

sxj731533730 1623

ACM 计算几何基础模板

在ACM计算几何中,我们常常重复用到许多方法,例如求点距,求直线方程,等等。不妨利用模板总结之。这些模板为我从网上学习后加入自己的理解糅合得来qwq,看了很多的博客,查了很多书籍,其中印象最深的是林夕林夕关于计算几何模板的总结,大家也可以去参考他的应该比我的更详细qwq(不过大佬最近好像出没比较少了) 所以我这个主要还是留着自己参考吧,能帮到他人再好不过了 为了不产生歧义,方便理解,本模板使用笛卡尔坐标系,封装的多是数学中常见的函数。 前置知识:高中数学 文章目录基础声明点向量直线 基础声明 首先,打acm

qq_39561693的博客 1507

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

ACM计算几何

本文出自:http://blog.youkuaiyun.com/svitter 北大ACM计算几何:线与线求交,线与面求交,求凸包,半平面求交等 Computational Geometry 计算几何 ACM中基本是最麻烦的部分。 几何代码都要自己写,ST...

chongkuachan8070的博客 100

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

计算几何系列 ——— 一切的开始

所有的游戏都有共性,多半免不了几何算法、图形、动画、渲染、UI等等,把这些通用的东西打包起来就形成了游戏引擎,如Unity3D、UE、Cocos等,游戏公司借助它们的力量便可以简化工作,从而专注于游戏内容制作。其他如机器人学中的寻路算法、分子建模领域的碰撞计算、以及邓俊辉老师课程中讲的“颜料勾兑问题”等等,对于其应用广泛性的总结借用Mark原话——“乍看起来,虽然某些领域似乎与几何风马牛不相及,然而它们同样可以借助几何算法而受益。换句话说,计算几何更像是算法的一个分支,而非几何学的分支。

Zz_0913的博客 3082

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

ACM总结之精度

ACM总结 1.最近

wkACM的专栏 1892

ACM模块解析之 计算几何

计算几何一.简介计算几何属于ACM算法中比较冷门的分类,在省赛中只在前几年考察过,这两年还没有考过,而且和高精度计算一样,遇到题目主要靠套模板,因此对题意的理解至关重要,而且往往题目描述还常为英文,所以还是需要一定的题量支撑,来判断具体考察的是什么。 二.题型分类下列仅为一部分,可与《算法与实现》第三章计算几何互相补充。1.点判断点是否在多边形中★★平面最近点对/最远点对★曼哈顿距离点集的有序化(...

popcjz的博客 1073

「计算几何精度问题」

本文转载自:传送门 在ACMACMACM中,精度问题非常常见。其中计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,让你debugdebugdebug半天都找不到错误出在哪。 浮点数为啥会有精度问题: 浮点数(以C/C++为准),一般用的较多的是float, double。 占字节数...

wzw 931

ACM中的浮点数精度处理

在ACM中,精度问题非常常见。其中计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,让你debug半天都找不到错误出在哪。 1.浮点数为啥会有精度问题: 浮点数(以C/C++为准),一般用的较多的是float, double。 占字节数 ...

一身清贫怎敢入繁华 529

ACM-计算几何之Cupid's Arrow——hdu1756

ACM 计算几何 Cupid's Arrow hdu1756 点在多边形内 射线法 射线法详解

继续激情,继续奋斗。 3189

ACM 计算几何中的精度问题

ACM 计算几何中的精度问题(转) (2013-03-17 16:40:03)转载▼ 标签: 精度 分类: 计算几何 http://www.cnblogs.com/acsmile/archive/2011/05/09/2040918.html 计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了。精度问题则不好说,有时候一个精度问题就可能成为一

wen_xp的专栏 568
上一篇: 2015.12杭电校赛 1008 Study Words
下一篇: hdu 1542 线段树求矩形并+离散化
QZQmmmm
博客等级 码龄11年 77粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值