数字对于 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;
问题在于您尝试创建它的方式(很可能),而不是因为它不适合。
如果您的代码中只有一个数字文字(即使您尝试将其分配给 double
或 long
),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;
显然,int
和long
都不能代表这个数字。 float
可以,但精度不够(假设我们使用最佳可用测量值)。
现在(post 2019)BigInteger
是最简单的正确表示。
现在,将常量声明为(各种)double
、long
和 BigInteger
.
时出现的明显问题
我希望你做了这样的事情:
double a = 602200000000000000000000;
等等。那是行不通的,但是需要解释它行不通的原因。问题是该数字是作为 int
文字提供的。 int
不可能那么大。最大可能的 int
值为 231 - 1 ... 比 2 x 109 大一点。
这就是 Java 编译器所抱怨的。字面量太大,无法成为 int
.
对于 long
文字来说也太大了。 (算一算。)
但对于 double
字面量来说并不算太大...只要你写得正确。
使用 BigInteger(String)
的解决方案之所以有效,是因为它通过使用字符串来回避将数字表示为数字文字的问题,并在运行时对其进行解析。从语言的角度来看,这没问题,但 (IMO) 错了,因为额外的精度是一种错觉。
很可能您正在使用 long
来初始化 BigInteger。由于 long
可以表示 64 位数字,因此您的数字太大而无法放入 long
。使用 String
会有所帮助。
我正在开发一个化学应用程序,我需要包括阿伏伽德罗数:
(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;
问题在于您尝试创建它的方式(很可能),而不是因为它不适合。
如果您的代码中只有一个数字文字(即使您尝试将其分配给 double
或 long
),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;
显然,int
和long
都不能代表这个数字。 float
可以,但精度不够(假设我们使用最佳可用测量值)。
现在(post 2019)BigInteger
是最简单的正确表示。
现在,将常量声明为(各种)double
、long
和 BigInteger
.
我希望你做了这样的事情:
double a = 602200000000000000000000;
等等。那是行不通的,但是需要解释它行不通的原因。问题是该数字是作为 int
文字提供的。 int
不可能那么大。最大可能的 int
值为 231 - 1 ... 比 2 x 109 大一点。
这就是 Java 编译器所抱怨的。字面量太大,无法成为 int
.
对于 long
文字来说也太大了。 (算一算。)
但对于 double
字面量来说并不算太大...只要你写得正确。
使用 BigInteger(String)
的解决方案之所以有效,是因为它通过使用字符串来回避将数字表示为数字文字的问题,并在运行时对其进行解析。从语言的角度来看,这没问题,但 (IMO) 错了,因为额外的精度是一种错觉。
很可能您正在使用 long
来初始化 BigInteger。由于 long
可以表示 64 位数字,因此您的数字太大而无法放入 long
。使用 String
会有所帮助。