我需要在java中编写一个方法来返回只有整数的幂,我希望这个方法返回-1或者如果数字超过Integer.MAX_VALUE则触发异常:
我尝试了第一个简单的步骤:
[]
上述方法是否准确,因为在调试后我发现当结果超过Integer.MAX_VALUE时它会转到负数,还是有另一种方法来处理这个?
答案 0 :(得分:4)
如果基数只能是正整数,那么您的方法将起作用。可能会发生下溢,你的基数是负整数,你的功率是一个奇数。
处理这种情况的一种简单但不是最佳的方法是使用长数据类型来存储输出并比较输出以检查它是否在Integer.MAX_VALUE和Integer.MIN_VALUE之间。
public static int GetPower(int base, int power){
long result = 1;
for(int i = 1; i <= power; i++)
{
result *= base;
if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
return -1;
}
}
return result;
}
答案 1 :(得分:3)
Nitram和PythaLye的答案有效,但我不喜欢使用其他数据类型来检查边界的想法。相反,我建议你使用这个简单的检查:
// This basically means result * base > boundary
if ((base > 0 && result > (Integer.MAX_VALUE / base))
|| (base < 0 && result < (Integer.MIN_VALUE / -base)) // Negative base case
{
return -1;
}
所以代码是:
public static int GetPower(int base, int power)
{
int result = 1;
for(int i = 1; i<=power; i++)
{
if ((base > 0 && result > (Integer.MAX_VALUE / base))
|| (base < 0 && result < (Integer.MIN_VALUE / -base)) {
return -1;
}
result *= base;
}
return result;
}
答案 2 :(得分:2)
您注意到的效果是数字溢出。
如果您向Integer.MAX_VALUE
添加一个,则会得到Integer.MIN_VALUE
。
现在您需要的是存储价值的更多空间。当你想在32位整数空间内工作时,你需要下一个更大的东西。这将是一个64位Long
值。与任何BigDecimals
用法相比,这在任何情况下都更快。
如果您的值超过Integer.MAX_VALUE
,则必须在任何循环步骤内检查并取消它,如果发生这种情况。
因此生成的代码将是这样的:
public static int GetPower(int base, int power)
{
long result = 1;
for(int i = 1; i <= power; i++)
{
result *= base;
if (result > Integer.MAX_VALUE) {
return -1;
}
}
return result;
}
此外,我建议您验证函数的输入,以确保基数不是负数。
答案 3 :(得分:2)
由于你有方法pow的简单实现,它不接受负数或值,我的建议是创建最高允许值,只需检查你的结果是否小于它。
public static int getPower(int base, int power)
{
int result = 1;
int maxAllowed = Integer.MAX_VALUE / base;
for(int i = 1; i<=power; i++)
{
result *= base;
if (i!=power && result>=maxAllowed){
return -1;
}
}
return result;
}
但总的来说,我强烈建议不要重新发明轮子,并使用Math.pow
方法
答案 4 :(得分:2)
如前所述,使用“更大”的数据类型可以进行验证并轻松计算 - 但是如果 没有更大的数据类型呢?
如果会导致溢出,您可以进行数学测试:
如果您正在计算base^power
,这意味着base^power = result
- 这也意味着power-th square of result = base
- 允许的最大结果为Integer.MAX_VALUE
- 否则您有溢出。
大于零的任何数字的power-th root
将始终在]0,number]
范围内 - 没有算术溢出的可能性。
那么 - 让我们将您使用的base
与power-th root
的{{1}}进行比较 - Integer.MAX_VALUE
LARGER ?然后你会遇到一个溢出 - 否则它会坚持(或等于)base
的结果
Integer.MAX_VALUE
导致
private static double powSafe(double base, int pow){
//this is the p-th root of the maximum integer allowed
double root = Math.pow(Integer.MAX_VALUE, 1.0/pow);
if (root < base){
throw new ArithmeticException("The calculation of " + base + "^" + pow + " would overflow.");
}else{
return Math.pow(base, pow);
}
}
public static void main(String[] argv)
{
double rootOfMaxInt = Math.pow(Integer.MAX_VALUE, 1.0/2);
try{
//that should be INTEGER.MAX_VALUE, so valid.
double d1 = powSafe(rootOfMaxInt, 2);
System.out.println(rootOfMaxInt + "^2 = " + d1);
}catch (ArithmeticException e){
System.out.println(e.getMessage());
}
try{
//this should overflow cause "+1"
double d2 = powSafe(rootOfMaxInt +1, 2);
System.out.println("("rootOfMaxInt + "+ 1)^2 = " + d1);
}catch (ArithmeticException e){
System.out.println(e.getMessage());
}
double the67thRootOfMaxInt = Math.pow(Integer.MAX_VALUE, 1.0/67);
try{
//and so, it continues
double d3 = powSafe(the67thRootOfMaxInt, 67);
System.out.println(the67thRootOfMaxInt + "^67 = " + d3);
double d4 = powSafe(the67thRootOfMaxInt +1, 67);
System.out.println("(" + the67thRootOfMaxInt + " + 1)^67 = " + d3);
}catch (ArithmeticException e){
System.out.println(e.getMessage());
}
}
注意,出现不精确的原因是double没有无限精度,这已经截断了表达式46340.950001051984^2 = 2.147483647E9
The calculation of 46341.950001051984^2 would overflow.
1.3781057199632372^67 = 2.1474836470000062E9
The calculation of 2.378105719963237^67 would overflow.
,因为2nd square of Integer.Max_Value
是奇数。
答案 5 :(得分:0)
你检查错了。尝试使用1&lt;&lt; 32和2作为参数的方法。
正确检查将类似于此result==result*base/base
,如果它是真的,那么您可以将result
和base
相乘而不会溢出。
答案 6 :(得分:0)
java.lang.Math中已经存在完全可行的幂函数。我强烈建议利用它来覆盖边缘情况。
public class GetPower {
public static int getPower(int base, int power) {
double result = Math.pow(base, power);
// check result in range
if (result > Integer.MAX_VALUE)
return -1;
if (result < Integer.MIN_VALUE)
return -1;
return (int) result;
}
public static void main(String[] args) {
for (int base=0; base<=10; ++base) {
for (int power=0; power<=10; ++power) {
int result = getPower(base, power);
System.out.println("getPower(" + base + ", " + power + ") = " + result);
}
}
}
}
没有必要重新发明轮子。无需担心浮点不准确 - 所有int值都可以完美表示为double。