2015-04-03 94 views
0

我试图解决这个问题,说以下内容:如何处理大量数据?

您应该计算第n个整数的和的平方与第一n整数的平方之和之间的差异。

当我输入一个很大的数字(例如4094574264)时,答案是否定的。为什么?它应该是一个正数。

Scanner scan = new Scanner(System.in); 
long input = scan.nextLong(); 
long answer = (input * (input + 1)/2)*(input * (input + 1)/2) - (input * (input + 1)) * ((input * 2) + 1)/6; 
System.out.println(answer); 

回答

0

你,我的朋友,正在体验overflow。这是当没有足够的位来描述你想解释的数字时,所以你最终会在一个大的循环中出现(因此是负数)。

如果您希望使用难以置信的大数字,解决方案是使用BigIntegerBigDecimal类。这些旨在创建任意精确数字。

2

的问题是在这条线

(input * (input + 1)/2)*(input * (input + 1)/2) - (input * (input + 1)) * ((input * 2) + 1)/6 

4094574264是一个33位有符号的数,因此input * (input + 1)需要66比特来存储,这溢出64位long。这并不包括后面的连续乘法,导致比64位大得多的结果。

如果你想要做的如此高的精度运算,使用的BigInteger代替

+0

您至少需要一个131位类型来计算上述表达式 – 2015-04-03 16:11:21

0

低级答案:

答案是否定的,因为你遇到了溢出。 JVM只能表示达到特定值(该类型的最大值)的数字。如果您执行的任何操作将数值增加到超过最大值,则它会“溢出”机器的表示能力并完全更改数字;在你的情况下,为负值。相反的情况适用于负面情况:如果我将负值减小到最小值以下,它将“流动”,我会得到一个非常大的正面答案。 “大数学”使用BigInteger(https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html)。