zoukankan      html  css  js  c++  java
  • 数值溢出(arithmetic overflow)问题与解决方案

    0. 典型场景

    • 两数相加(乘法)、两数相减、一个数的阶乘,一个数的幂,这些统统可能造成数值的溢出;
    • 避免数值溢出的方法:
      • 当把一个计算出的很大的数赋值给一个 int(2^31-1)类型变量存储时,一般会溢出,这个时候可以采用取模的方式进行溢出的避免;

    如,不能用表达式 xy<0 取代 x<yxy 可能会造成数值溢出,同样地也不能用表达式 y<x,在补码表示中正数和负数(+0和-0 是不同的数)的范围是不对称的。

    1. 求最小公倍数

    • 根据最大公约数求最小公倍数;

      lcm(a,b)=abgcd(a,b)

      int gcd(int a, int b);
      int lcm(int a, int b){
          return (a * b)/gcd(a, b);
      }

      数学意义上确实没有异议,但在编程实现时,考虑到计算机表示能力的限制,计算最小公倍数时,中间需要计算二者的乘积 a*b,乘法容易造成数值的上溢;

      int lcm(int a, int b){
          return a * (b / gcd(a, b));
      }

    2. 求组合数时

    (nr)=n!(nr)!r!

    中间的 n! 在某些输入的情况下,其值也会十分可观(上溢)。

    此时可以使用递归式计算组合数:

    (nr)=(n1r)+(n1r1)

    int comb(int n, int r){
        if (n == r) return 1;
        if (n == 0 || r == 0) return 1;
        return comb(n - 1, r) + comb(n - 1, r - 1);
    }
  • 相关阅读:
    Physics Experiment POJ3684
    FLIPTILE POJ NO.3279
    [蓝桥杯][算法提高VIP]盾神与积木游戏
    棋盘问题
    出栈次数的DFS计算
    Bribe the Prisoners
    Crazy Rows
    关于部分“记录”密码获取^o^/
    NOIP2017爆炸记
    【luogu 1024 一元三次方程求解】二分思想
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9423941.html
Copyright © 2011-2022 走看看