0. 典型场景
- 两数相加(乘法)、两数相减、一个数的阶乘,一个数的幂,这些统统可能造成数值的溢出;
- 避免数值溢出的方法:
- 当把一个计算出的很大的数赋值给一个 int(2^31-1)类型变量存储时,一般会溢出,这个时候可以采用取模的方式进行溢出的避免;
如,不能用表达式 x−y<0 取代 x<y,x−y 可能会造成数值溢出,同样地也不能用表达式 −y<−x,在补码表示中正数和负数(+0和-0 是不同的数)的范围是不对称的。
1. 求最小公倍数
根据最大公约数求最小公倍数;
lcm(a,b)=a⋅bgcd(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!(n−r)!r!
中间的 n! 在某些输入的情况下,其值也会十分可观(上溢)。
此时可以使用递归式计算组合数:
(nr)=(n−1r)+(n−1r−1)
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);}