【C++】NOIP复赛学习之旅 10/17

本文深入探讨了浮点误差产生的原因,及如何通过定义特定函数处理浮点数比较问题。同时,介绍了在C++中为何及如何重载运算符,以实现结构体之间的比较与操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浮点误差处理


为什么会出现浮点误差

所有的整数和小数都是通过二进制储存在电脑中的。在存较大整数的时候,例如存储 12 345 678 901 234 567 890时,我们存储时会因为有效数字的问题丢失一些有效数字,然而对0.6这种小数来讲,我们会发现在储存这种小数时因为有效数位的限制(对于binary64,通常是53位),我们发现这个0.6这个数需要舍弃数位。对于这种情况,根据IEEE提供RoundTiesToEven方法1,我们经常会发现0.6转换成BIN再转换成DEC经常会小数点后遥远的数位多一个1或少一个1.


如何处理浮点误差

对于判断两个浮点数的是否相等与大小,我们可以定义一个三出口的函数2

int sgn(double a){
	return a<-eps?-1:a<eps?0:1;
}

eps是ε的英文读音简写。eps表示的是一个较小的量,它要被确保远大于浮点数的不确定量。我们通常取为1E-8 。
对于任何两个需要比较的浮点数,只需要将左值与右值作差并当作参数传入sgn() 函数中,将返回值与0进行欲进行的比较即可。我们简单地举个例子。

double a=0.6,b=0.4;
//This is the usual method
bool re1=(a<=b)
//This is the improved method
bool re2=(sgn(a-b)<=0);

结构体重载运算符


为什么要重载运算符

举一个最简单的例子。我们现在在priority_queue< Pivots > pvts里储存了很多个名为Pivots的结构体。优先队列里的比较大小必定是使用了>和<进行排序,但是这些运算符如果直接应用在结构体上必定会报错,因为运算符不知道如何比较两个结构体的大小。这时就需要我们对于这个结构体进行运算符重载。


重载运算符的规则
  1. 只有五个运算符不可以重载,他们分别是

    • 成员访问运算符(.)
    • 成员指针访问运算符(.*)
    • 域运算符(::)
    • 长度运算符(sizeof)
    • 条件运算符(?)
  2. 不允许新定义运算符。

  3. 不允许改变运算符参数个数。

  4. 不允许给运算符添加默认的参数


重载后运算符的性质
  1. 重载后运算符的优先级不改变。

  2. 重载后运算符的结合性不改变。

  3. 重载后的运算符重载的内容只对用户自定义的类型和对象有效。


重载运算符的方法

首先我们先来定义一个结构体Edge

struct Edge{
	int s;
	int v;
	int weight;
	//bookmark 1#
}

然后为了举例,我们来重载运算符+和<

//The following snippet is to be inserted into the place of bookmark #1
Edge operator+(const Edge &other){
	Edge newE;
	newE.s=s+other.s;
	newE.v=v+othe.v;
	newE.weight=weight+other.weight;
	return newE;
}
bool operator<(const Edge &other){
	return cost<other.other;
}

  1. http://babbage.cs.qc.cuny.edu/IEEE-754/ 和http://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html 是两个有用的网站,它们可以演示IEEE在Round方法方面上采取的办法执行出来的效果。感谢优快云用户h124668269的整理。 ↩︎

  2. https://wenku.baidu.com/view/b6b7ccea551810a6f52486bf### 这个文档介绍了许多关于计算精度的问题。感谢优快云用户yiqzq的整理! ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值