尽管使用 Long 原始类型和大整数,但大斐波那契数列的整数溢出
Integer overflow for large a Fibonnaci sequence despite using Long primitive type and Big Integer
我正在编写一个程序来打印第 n 个斐波那契数。
方法FIBBO(int n) 使用long 和BigInteger 类型的组合来存储Fibonacci 运算的结果。当认为 prev+next>Long.MAX_VALUE 使用 big_flag 时,该方法应该切换到使用 BigInteger .但是这个程序只有在我在第二个循环中使用 Integer.MAX_VALUE 时才有效。
当我使用 Long.MAX_VALUE 时,无论 n 的值有多大,big_flag 的第二个循环现在都不会触发,我只会得到垃圾值。我不明白为什么当我使用 Long.MAX_VALUE.
时我的溢出逻辑从未被激活
import java.util.*;
import java.math.*;
public class fibbo_iteration{
public static void main(String argss[])
{
BigInteger result;
Scanner input=new Scanner(System.in);
int n=0;
System.out.println("Enter number of terms for fibbonacci sequence");
n=input.nextInt();
if(n<0){
System.out.println("Fibbonaci sequence cannot be generated for the entered negative value");
System.exit(1);
}
result=fibbo_iteration.FIBBO(n); //call
System.out.println(result.toString());
}
static BigInteger FIBBO(int n)
{
// variables
long sum=0L,prev=0L,next=1L;
BigInteger big_prev=new BigInteger("0"),big_next=new BigInteger("0"),big_sum=new BigInteger("0");
boolean big_flag=false;
for(int i=0;i<n;i++){
if(big_flag){
// System.out.println(big_sum.toString()); to use when printing a series upto n
big_prev=big_next;
big_next=big_sum;
big_sum=big_prev.add(big_next);
}
else if(prev+next>Long.MAX_VALUE){ // ***The program works abolutely correct if i replace LONG.MAX_VALUE with Integer.MAX_Value***
big_prev=new BigInteger(String.valueOf(prev));
big_next=new BigInteger(String.valueOf(next));
big_sum=big_prev.add(big_next);
big_flag=true; // this is supposed to signal the switch to BigInteger
System.out.println("Value exceeds Long");
}
else{
if(i==1){ // this if block accomodates the eccentricity of starting the fibbonaci sequence
sum=1L;
continue;
}
sum=prev+next;
prev=next;
next=sum;
System.out.println(sum);
}
}
return big_flag==true?big_sum:new BigInteger(String.valueOf(sum));
}
}
Long 的最大值实际上是该类型的最大值。任何高于此的计算都会给您……您显然没有预料到的好结果。 prev+next>Long.MAX_VALUE
这种检查是无稽之谈。永远不会是真的。
应该使您的程序正常工作的一点更改是:prev > Long.MAX_VALUE - next
如果想更详细的了解,可以照我写的那样对比调试,在if块里面下个断点。尝试查看 prev+next
的值。看看它是如何变成负值的。这是因为您已达到 long
无法存储的值。
使用Math.addExact(long,long)
。使用 try-catch 包围并在抛出异常时切换到 BigInteger。
try
{
sum=Math.addExact(prev, next);
prev=next;
next=sum;
System.out.println(sum);
}
catch(ArithmeticException overflow)//Out of range
{
big_prev=new BigInteger(String.valueOf(prev));
big_next=new BigInteger(String.valueOf(next));
big_sum=big_prev.add(big_next);
big_flag=true; // this is supposed to signal the switch to BigInteger
System.out.println("Value exceeds Long");
}
此代码段应放置在对应于 if(big_flag)
的 else
块中。
另见 Integer Overflow。
我正在编写一个程序来打印第 n 个斐波那契数。
方法FIBBO(int n) 使用long 和BigInteger 类型的组合来存储Fibonacci 运算的结果。当认为 prev+next>Long.MAX_VALUE 使用 big_flag 时,该方法应该切换到使用 BigInteger .但是这个程序只有在我在第二个循环中使用 Integer.MAX_VALUE 时才有效。
当我使用 Long.MAX_VALUE 时,无论 n 的值有多大,big_flag 的第二个循环现在都不会触发,我只会得到垃圾值。我不明白为什么当我使用 Long.MAX_VALUE.
时我的溢出逻辑从未被激活import java.util.*;
import java.math.*;
public class fibbo_iteration{
public static void main(String argss[])
{
BigInteger result;
Scanner input=new Scanner(System.in);
int n=0;
System.out.println("Enter number of terms for fibbonacci sequence");
n=input.nextInt();
if(n<0){
System.out.println("Fibbonaci sequence cannot be generated for the entered negative value");
System.exit(1);
}
result=fibbo_iteration.FIBBO(n); //call
System.out.println(result.toString());
}
static BigInteger FIBBO(int n)
{
// variables
long sum=0L,prev=0L,next=1L;
BigInteger big_prev=new BigInteger("0"),big_next=new BigInteger("0"),big_sum=new BigInteger("0");
boolean big_flag=false;
for(int i=0;i<n;i++){
if(big_flag){
// System.out.println(big_sum.toString()); to use when printing a series upto n
big_prev=big_next;
big_next=big_sum;
big_sum=big_prev.add(big_next);
}
else if(prev+next>Long.MAX_VALUE){ // ***The program works abolutely correct if i replace LONG.MAX_VALUE with Integer.MAX_Value***
big_prev=new BigInteger(String.valueOf(prev));
big_next=new BigInteger(String.valueOf(next));
big_sum=big_prev.add(big_next);
big_flag=true; // this is supposed to signal the switch to BigInteger
System.out.println("Value exceeds Long");
}
else{
if(i==1){ // this if block accomodates the eccentricity of starting the fibbonaci sequence
sum=1L;
continue;
}
sum=prev+next;
prev=next;
next=sum;
System.out.println(sum);
}
}
return big_flag==true?big_sum:new BigInteger(String.valueOf(sum));
}
}
Long 的最大值实际上是该类型的最大值。任何高于此的计算都会给您……您显然没有预料到的好结果。 prev+next>Long.MAX_VALUE
这种检查是无稽之谈。永远不会是真的。
应该使您的程序正常工作的一点更改是:prev > Long.MAX_VALUE - next
如果想更详细的了解,可以照我写的那样对比调试,在if块里面下个断点。尝试查看 prev+next
的值。看看它是如何变成负值的。这是因为您已达到 long
无法存储的值。
使用Math.addExact(long,long)
。使用 try-catch 包围并在抛出异常时切换到 BigInteger。
try
{
sum=Math.addExact(prev, next);
prev=next;
next=sum;
System.out.println(sum);
}
catch(ArithmeticException overflow)//Out of range
{
big_prev=new BigInteger(String.valueOf(prev));
big_next=new BigInteger(String.valueOf(next));
big_sum=big_prev.add(big_next);
big_flag=true; // this is supposed to signal the switch to BigInteger
System.out.println("Value exceeds Long");
}
此代码段应放置在对应于 if(big_flag)
的 else
块中。
另见 Integer Overflow。