取模与浮点数精度运算

版权声明: https://blog.csdn.net/qq_38234381/article/details/82078848
int a=1e9, b=1e9, c=a*b;
//毫无疑问c的值会不准确 
int a=1e9, b=1e9;
long long c=a*b;
//这样子其实与上面的没什么区别,因为a*b已经爆掉了,在赋给c还是一样
int a=1e9, b=1e9;
long long c=(long long)(a*b);//同上,a*b已经爆掉
long long a=1e9, b=1e9, c=a*b;//这是最保险的方法 

再说下取膜。在很多题目中,往往都会让我们将答案膜上一个大质数(大约是int级别的),这是因为在这些题目中,如果不膜一定会爆数据类型,使答案无法估测。但要是取膜的话我们就可以保证每一步运算(对答案取膜可以转化到对每一步运算取膜,取膜的一个性质)都在我们的膜数范围之内(这也是膜数不会达到longlong的一个原因,因为太大就容易爆),这样就保证了答案和正解一样而且还不会爆数据类型。

最后是浮点数,很多要输出浮点数的题目都会让我们保留几位小数输出,原因如下:

先明确一点,即保留2位小数和两个浮点数相差要小于0.01才视为相等是一致的,具体自己举几个例子就明白了(由于不同IDE有不同的规则,这里就拿最基本的四舍五入为规则)。然后我们之所以这样做是因为浮点数计算的约等性。如假设我们有两个浮点数a和b,题目让我们保留2位小数输出它们相乘的结果(正解是3.14)。我们让它们相乘,可能得到3.13999999或者3.1411111这类的结果,就是说在没有规定的情况下它们与正解是不相等的,但如果我们规定了,那么就会得到3.14这一个结果(规定可以理解为允许有误差,从实际的角度考虑就是过小的部分可以忽略不计了),从而保证题目有唯一的解。

除了本来相乘就严格相等的浮点数之外,我们都要用这种方式来判断两个浮点数是否相等,当然也可以都用这种方式(推荐),这样更加严谨嘛。

精度的题目可以做一下这道题:https://www.luogu.org/problemnew/show/P2831

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2018/9/27

对于取模运算有了一些新的理解:

首先是取模运算的一些性质

运算规则

模运算与基本四则运算有些相似,但是除法例外。其规则如下:

  1. (a + b) % p = (a % p + b % p) % p (1)

  2. (a - b) % p = (a % p - b % p) % p (2)

  3. (a * b) % p = (a % p * b % p) % p (3)

  4. a ^ b % p = ((a % p)^b) % p (4)

  • 结合律:

    ((a+b) % p + c) % p = (a + (b+c) % p) % p (5)

        ((a*b) % p * c)% p = (a * (b*c) % p) % p (6)

  • 交换律:

    (a + b) % p = (b+a) % p (7)

        (a * b) % p = (b * a) % p (8)

  • 分配律:

    (a+b) % p = ( a % p + b % p ) % p (9)

    ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (10)

以上摘自百度百科

其实上面的公式了解一下即可,在大多数题目都是可以随意模的。

在取模的同时要始终牢记我们取模是为了让最终的答案在模数之内,所以在写程序时(在判断可以取模后)如果一旦发现爆了的数据类型,那么就赶紧取模即可。

另外就是我们模大质数是为了防止冲突(hash冲突),在取模运算中没有硬性规定模数一定是质数。

可以做一下这道题:https://www.luogu.org/problemnew/show/P2312

猜你喜欢

转载自blog.csdn.net/qq_38234381/article/details/82078848