c++bug小结(一)

昨天打codeforces,碰到两个bug,在此总结。

用一元二次方程求解公式的精度问题

1、在这里用一元二次方程求解公式之后,由于数据较大极有可能造成精度不高导致转化int类型之后与实际结果差1或着差2。
如公式x*x+x-c>=0,求出满足公式的最小整数x。
这里用一元二次方程求解,由于精度的问题,导致无法得到正确结果。此时将公式转化一下 x*x+x > =c,
假设x*x+x =c,
则 x < sqrt(x*x+x) < x+1
即有x < sqrt(c) < x+1。
所以求出sqrt(c)的上界i,并逐渐递减判断是否i*i+i>=c,是就继续递减,否则得出结果。

无法整除的乘除法运算不能调换

a/b*x 与a*x/b看似这两个步骤得出的结果一样,其实不然。
举个例子,a = 3,b=2, x = 2
式一得出结果 2,式二得出结果3
这也是在写codeforces的拓展欧几里德算法找了一两个小时找到的bug。。
如下:
错误写法:y-=a*x/b;

long long gcd(long long a, long b, long long &x, long long & y) {
    if (!b) {
        x = 1;
        y = 0;
        return a;
    }
    long long g = gcd (b, a%b, y, x);
    y -= a*x/b;
    return g;
}

正确写法:y-=a/b*x;

long long gcd(long long a, long b, long long &x, long long & y) {
    if (!b) {
        x = 1;
        y = 0;
        return a;
    }
    long long g = gcd (b, a%b, y, x);
    y -= a/b*x;
    return g;
}

关于对拓展欧几里德算法的推导,见我以前的文章:

拓展欧几里德算法推导

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值