数字对于 BigInteger 来说太大了

Number too big for BigInteger

我正在开发一个化学应用程序,我需要包括阿伏伽德罗数: (602200000000000000000000)

不知道能不能用科学记数法表示为6.022 x 10x23(不能放指数)

我先用了double,然后是long,现在,我用了java.math.BigInteger

但它仍然说它太大了,我该怎么办,或者这对系统来说应该够大了吧?

将它作为 String 传递给 BigInteger 构造函数,它工作得很好。

BigInteger a = new BigInteger("602200000000000000000000");
a = a.multiply(new BigInteger("2"));
System.out.println(a);

输出:1204400000000000000000000

您可以使用E记数法来书写科学记数法:

double a = 6.022e23;

问题在于您尝试创建它的方式(很可能),而不是因为它不适合。

如果您的代码中只有一个数字文字(即使您尝试将其分配给 doublelong),this is first treated as an integer(在转换为类型之前它需要),并且您拥有的数字不能放入整数中。

// Even though this number can fit into a long, it won't compile, because it's first treated
// as an integer.
long l = 123456788901234;

要创建多头,您可以将 L 添加到您的号码,因此 602200000000000000000000L,尽管它也不适合多头 - the max value is 263-1.

要创建双倍,您可以将 .0 添加到您的号码,因此 602200000000000000000000.0(或 Guffa 建议的 6.022e23),但如果您想要精确,则不应使用它值,因为您可能会因为存储值的方式而失去一些准确性。

要创建 BigInteger,您可以使用 the constructor taking a string parameter:

new BigInteger("602200000000000000000000");

首先,你需要检查你的物理/化学教科书。

阿伏伽德罗数不是 602,200,000,000,000,000,000,000。它是 大约 6.022 x 1023。关键词是"approximately"。截至2019年,精确值为6.02214076×1023 mol−1

(2015年我最初写这个回复的时候,阿伏加德罗数目前最好的近似是6.022140857(74)×1023 mol−1,相对误差为+/- 1.2×10–8。2019年SI重新定义摩尔/阿伏加德罗数为上述精确值。资料来源:Wikipedia)

我最初(2015 年)的回答是,由于该数字只需要 8 位十进制数字的精度,因此 Java double 类型是表示它的合适类型。因此,我推荐:

final double AVOGADROS_CONSTANT = 6.02214076E23;

显然,intlong都不能代表这个数字。 float 可以,但精度不够(假设我们使用最佳可用测量值)。

现在(post 2019)BigInteger是最简单的正确表示。


现在,将常量声明为(各种)doublelongBigInteger.

时出现的明显问题

我希望你做了这样的事情:

  double a = 602200000000000000000000;

等等。那是行不通的,但是需要解释它行不通的原因。问题是该数字是作为 int 文字提供的。 int 不可能那么大。最大可能的 int 值为 231 - 1 ... 比 2 x 109 大一点。

这就是 Java 编译器所抱怨的。字面量太大,无法成为 int.

对于 long 文字来说也太大了。 (算一算。)

但对于 double 字面量来说并不算太大...只要你写得正确。

使用 BigInteger(String) 的解决方案之所以有效,是因为它通过使用字符串来回避将数字表示为数字文字的问题,并在运行时对其进行解析。从语言的角度来看,这没问题,但 (IMO) 错了,因为额外的精度是一种错觉。

很可能您正在使用 long 来初始化 BigInteger。由于 long 可以表示 64 位数字,因此您的数字太大而无法放入 long。使用 String 会有所帮助。