简体   繁体   English

如何处理大数?

[英]How to handle large numbers?

I am trying to solve the following problem我正在尝试解决以下问题

you should calculate the difference between the square of the sum of the first n integers and the sum of the squares of the first n integer.您应该计算前 n 个整数之和的平方与前 n 个整数的平方和之差。

When I enter a large number (eg 4094574264) the answer is negative.当我输入一个大数字(例如 4094574264)时,答案是否定的。 Why?为什么? It should be a positive number.它应该是一个正数。

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);

The problem is in this line问题出在这一行

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

4094574264 is a 33-bit signed number, therefore input * (input + 1) will need 66 bits to store, which overflows 64-bit long . 4094574264 是一个 33 位有符号数,因此input * (input + 1)将需要66 位来存储,这会溢出 64 位long That's not counting the series of multiplications later, resulting in a result much larger than 64 bits.这不包括后面的一系列乘法,导致结果远大于 64 位。

If you want to do such high precision arithmetic, use BigInteger instead如果你想做这么高精度的算术,请改用BigInteger

You, my friend, are experiencing overflow .你,我的朋友,正在经历溢出 This is when there aren't enough bits to describe the number that you want to explain, so you end up going around in a big loop (hence the negative numbers).这是当没有足够的位来描述您想要解释的数字时,因此您最终会陷入一个大循环(因此是负数)。

The solution, if you wish to use incredibly large numbers, is to use the BigInteger and BigDecimal class.如果您希望使用非常大的数字,解决方案是使用BigIntegerBigDecimal类。 These are designed to create arbitrary precision numbers.这些旨在创建任意精度的数字。

Low-level answer:低级答案:

The answer is negative because you're experiencing overflow.答案是否定的,因为您正在经历溢出。 The JVM can only represent numbers up to a certain value (the maximum for that type.) If you perform any operation which increases a value beyond the maximum, it "flows over" the machine's representation capabilities and changes the number completely; JVM 只能表示达到某个值(该类型的最大值)的数字。如果您执行任何将值增加到超过最大值的操作,它会“溢出”机器的表示能力并完全改变数字; in your case, to a negative value.在您的情况下,为负值。 The opposite applies to negatives: if I decrease a negative value below the minimum, it will "flow under" and I will get an answer that is a very large positive.相反的情况适用于负数:如果我将负值降低到最小值以下,它将“向下流动”,我会得到一个非常大的正数答案。 Use BigInteger ( https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html ) for "large math."将 BigInteger ( https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html ) 用于“大型数学”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM