Java 多头中的斐波那契计算显示负数
Fibonacci calculation in Java Longs shows up negative
我的 Fibonacci 计算器工作正常,但是当数字上升到更高时,结果会变成负数,就像它超过最大值 Integer
一样。
它正在使用缓存 java.util.Map<Integer, Long>
。进入 Map
的所有内容都完全符合预期,但是当打印出来时我得到例如对于 291:
-784134397488903422
根据http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibCalcX.html,应该是:
2923602405716568564338475449381171413803636207598822186175234
我的 Long
似乎出了点问题,但我还不确定具体是什么。有人能给我指出正确的方向吗?
Map
个条目的值:
http://pastebin.com/uje07Ays
java 有 8 个 primitive data types
字节
- 最小值为 -128 (-2^7)
- 最大值为127(含)(2^7 -1)
- 默认值为 0
短
- 最小值为 -32,768 (-2^15)
- 最大值为32,767(含)(2^15 -1)
- 默认值为 0。
- short数据类型也可以作为byte数据类型来保存内存。 short 比 int 小 2 倍(但java将此类型改为 int 进行计算)
整数
- 最小值为 - 2,147,483,648。(-2^31)
- 最大值为2,147,483,647(含).(2^31 -1),比你的数字多
- Int 通常用作整数值的默认数据类型
除非担心内存问题。
- 默认值为 0。
长
- 最小值为-9,223,372,036,854,775,808。(-2^63)
- 最大值为9,223,372,036,854,775,807(含)。 (2^63 -1) 这个值小于你的数字
- 当需要比 int 更宽的范围时使用此类型。
- 默认值为 0L。
浮动
- Float 数据类型是单精度 32 位 IEEE 754 浮点数。
- float主要用于大型浮点数组节省内存
数字。使用这种类型的 int 值是犯罪
- 默认值为 0.0f。
双
- double 数据类型是双精度 64 位 IEEE 754 浮点数
点.
- 这种数据类型一般用作小数的默认数据类型
值,一般默认选择。
- Double 数据类型不应该用于精确值,例如
货币。
- 默认值为 0.0d。
布尔值
- 布尔数据类型表示一位信息。
- 只有两个可能的值:true 和 false。
- 此数据类型用于跟踪 true/false 的简单标志
条件。
- 默认值为 false。
字符
- har 数据类型是单个 16 位 Unicode 字符。
- 最小值为“\u0000”(或 0)。
- 最大值为“\uffff”(或 65,535,含 65,535)。
- Char数据类型用于存储任何字符。
如您所见,上述类型的 none 可以存储您的值,因此您必须使用 BigInteger (example) 或任何其他可以处理此大值的 class。
我认为您超过了 Java 用于 long 类型的有符号 64 位整数中可以存储的最大 long 值,有关 Long 和这些的更多信息在 Java API:http://docs.oracle.com/javase/7/docs/api/java/lang/Long.html。
64位有符号整数的最大正数为2^63 -1:9 223 372 036 854 775 807
,你的值好像已经达到这个限制,如果有符号整数的最高位是1,那么有符号整数变为负数(有关更多详细信息,请参阅 2 补整数:http://en.wikipedia.org/wiki/Two%27s_complement)。
您需要使用 BigInteger 来获得任意精度的整数 http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html。
public static void main(String[] args)
{
Map<Integer, BigDecimal> fibonacciMap = new HashMap<Integer, BigDecimal>();
fibonacciMap.put(1, BigDecimal.valueOf(1));
fibonacciMap.put(2, BigDecimal.valueOf(1));
System.out.println(1 + " : " + fibonacciMap.get(1));
System.out.println(2 + " : " + fibonacciMap.get(2));
for(int i=3;i<=300;i++)
{
fibonacciMap.put(i, fibonacciMap.get(i-1).add(fibonacciMap.get(i-2)));
System.out.println(i + " : " + fibonacciMap.get(i));
}
}
因为,java 中 long 的最大值是 9223372036854775807。因此,当斐波那契数超过此最大值时,它开始从 -9223372036854775808(最小值)到零到 9223372036854775807(最大值)四舍五入).因此,我们需要使用 BigDecimal 而不是 Long 来避免 -ve 值。
例如:
Fib[92]=7540113804746346429
Fib[91]=4660046610375530309
(BigDecimal)Fib[93]=Fib[91]+Fib[92]=12200160415121876738 大于 Long.MAX_VALUE
(长)Fib[93]= -6246583658587674878
Long.MAX_VALUE = 9223372036854775807
Long.MIN_VALUE = -9223372036854775808
所以,
(BigDecimal)Fib[93] = Long.MAX_VALUE - (Long.MIN_VALUE - (Long)Fib[93]) + 1;
我的 Fibonacci 计算器工作正常,但是当数字上升到更高时,结果会变成负数,就像它超过最大值 Integer
一样。
它正在使用缓存 java.util.Map<Integer, Long>
。进入 Map
的所有内容都完全符合预期,但是当打印出来时我得到例如对于 291:
-784134397488903422
根据http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibCalcX.html,应该是:
2923602405716568564338475449381171413803636207598822186175234
我的 Long
似乎出了点问题,但我还不确定具体是什么。有人能给我指出正确的方向吗?
Map
个条目的值:
http://pastebin.com/uje07Ays
java 有 8 个 primitive data types
字节
- 最小值为 -128 (-2^7)
- 最大值为127(含)(2^7 -1)
- 默认值为 0
短
- 最小值为 -32,768 (-2^15)
- 最大值为32,767(含)(2^15 -1)
- 默认值为 0。
- short数据类型也可以作为byte数据类型来保存内存。 short 比 int 小 2 倍(但java将此类型改为 int 进行计算)
整数
- 最小值为 - 2,147,483,648。(-2^31)
- 最大值为2,147,483,647(含).(2^31 -1),比你的数字多
- Int 通常用作整数值的默认数据类型 除非担心内存问题。
- 默认值为 0。
长
- 最小值为-9,223,372,036,854,775,808。(-2^63)
- 最大值为9,223,372,036,854,775,807(含)。 (2^63 -1) 这个值小于你的数字
- 当需要比 int 更宽的范围时使用此类型。
- 默认值为 0L。
浮动
- Float 数据类型是单精度 32 位 IEEE 754 浮点数。
- float主要用于大型浮点数组节省内存 数字。使用这种类型的 int 值是犯罪
- 默认值为 0.0f。
双
- double 数据类型是双精度 64 位 IEEE 754 浮点数 点.
- 这种数据类型一般用作小数的默认数据类型 值,一般默认选择。
- Double 数据类型不应该用于精确值,例如 货币。
- 默认值为 0.0d。
布尔值
- 布尔数据类型表示一位信息。
- 只有两个可能的值:true 和 false。
- 此数据类型用于跟踪 true/false 的简单标志 条件。
- 默认值为 false。
字符
- har 数据类型是单个 16 位 Unicode 字符。
- 最小值为“\u0000”(或 0)。
- 最大值为“\uffff”(或 65,535,含 65,535)。
- Char数据类型用于存储任何字符。
如您所见,上述类型的 none 可以存储您的值,因此您必须使用 BigInteger (example) 或任何其他可以处理此大值的 class。
我认为您超过了 Java 用于 long 类型的有符号 64 位整数中可以存储的最大 long 值,有关 Long 和这些的更多信息在 Java API:http://docs.oracle.com/javase/7/docs/api/java/lang/Long.html。
64位有符号整数的最大正数为2^63 -1:9 223 372 036 854 775 807
,你的值好像已经达到这个限制,如果有符号整数的最高位是1,那么有符号整数变为负数(有关更多详细信息,请参阅 2 补整数:http://en.wikipedia.org/wiki/Two%27s_complement)。
您需要使用 BigInteger 来获得任意精度的整数 http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html。
public static void main(String[] args)
{
Map<Integer, BigDecimal> fibonacciMap = new HashMap<Integer, BigDecimal>();
fibonacciMap.put(1, BigDecimal.valueOf(1));
fibonacciMap.put(2, BigDecimal.valueOf(1));
System.out.println(1 + " : " + fibonacciMap.get(1));
System.out.println(2 + " : " + fibonacciMap.get(2));
for(int i=3;i<=300;i++)
{
fibonacciMap.put(i, fibonacciMap.get(i-1).add(fibonacciMap.get(i-2)));
System.out.println(i + " : " + fibonacciMap.get(i));
}
}
因为,java 中 long 的最大值是 9223372036854775807。因此,当斐波那契数超过此最大值时,它开始从 -9223372036854775808(最小值)到零到 9223372036854775807(最大值)四舍五入).因此,我们需要使用 BigDecimal 而不是 Long 来避免 -ve 值。
例如:
Fib[92]=7540113804746346429
Fib[91]=4660046610375530309
(BigDecimal)Fib[93]=Fib[91]+Fib[92]=12200160415121876738 大于 Long.MAX_VALUE
(长)Fib[93]= -6246583658587674878
Long.MAX_VALUE = 9223372036854775807
Long.MIN_VALUE = -9223372036854775808
所以, (BigDecimal)Fib[93] = Long.MAX_VALUE - (Long.MIN_VALUE - (Long)Fib[93]) + 1;