我正在开发一个化学应用程序,我需要包括阿伏加德罗常数: (602200000000000000000000
)数太大的BigInteger
我真的不知道我是否可以用科学记数法表示它6.022 x 10x23
(不能放指数)。
我第一次使用double
,然后long
现在,我用java.math.BigInteger
。
但它仍然说它太大了,我该怎么做或应该这样做对于一个系统来说很重要?
我正在开发一个化学应用程序,我需要包括阿伏加德罗常数: (602200000000000000000000
)数太大的BigInteger
我真的不知道我是否可以用科学记数法表示它6.022 x 10x23
(不能放指数)。
我第一次使用double
,然后long
现在,我用java.math.BigInteger
。
但它仍然说它太大了,我该怎么做或应该这样做对于一个系统来说很重要?
首先,你需要检查你的物理/化学课本。
阿伏加德罗的号码不是602,200,000,000,000,000,000,000。它是大约 6.022 x 10 。关键词是“大约”。这个数字是一个经验测量值。
(根据Wikipedia,目前最好的近似是6.022140857(74)×10 摩尔-1,相对误差为±1.2×10 -8 。)
由于该数字仅约为8位十进制数字的精度,因此Java double
类型是一种适当的类型来表示它。因此,我会用
final double AVOGADROS_CONSTANT = 6.02214085774E23;
显然,无论是int
或long
可以代表这个数字。 A float
可能但不够精确(假设我们使用最佳可用测量值)。 BigInteger
是一种可能性,但它在概念上是错误的,因为我们实际上并没有一个确切的常量整数值。
现在您的与声明的常数(不同)的double
,一个long
和BigInteger
明显的问题。
我希望你做了这样的事情:
double a = 602200000000000000000000;
等。这是行不通的,但它不起作用的原因需要解释。问题在于该号码是以文字形式提供的int
。一个int
不能那么大。尽可能最大的int
值为2 - 1 ...这比2 x 10大一点点。。
这就是Java编译器所抱怨的。字面太大而不能成为int
。
对于long
字面值也太大了。 (做数学)
但是它不是太大的文字double
......只要你写得正确。
使用BigInteger(String)
的解决方案的工作原理是,它通过使用字符串代替数字字面值并在运行时解析数字文字来解决数字问题。从语言的角度来看没什么问题,但(IMO)错了,因为额外的精确度是一种错觉。
将它作为String
传递给BigInteger构造函数,它工作得很好。
BigInteger a = new BigInteger("602200000000000000000000");
a = a.multiply(new BigInteger("2"));
System.out.println(a);
输出:1204400000000000000000000
谢谢,好像我的大部分程序将在字符串参数中定义。但为什么它可以表示为一个字符串,但它不能作为一个整数? –
@AntonioAguilar这是因为当你尝试将它传递给BigInteger构造函数,比如BigInteger a = new BigInteger(602200000000000000000000);那么首先将该数字解析为一个int。显然,尽管它不适合int,但它肯定会适合BigInt。为了规避这种情况,您将该数字作为字符串传递。有关更多详细信息,请参阅Dukeling的答案。 – Rishav
您可以使用E符号写的科学记数法:
double a = 6.022e23;
的问题是你怎么想创建它(最有可能),不因为它不适合。
如果你只是一个数字的文字在你的代码(即使你试图将其分配到一个double
或long
)(被转换为需要的类型为前),this is first treated as an integer,而且数量,你有可以” t适合一个整数。
// Even though this number can fit into a long, it won't compile, because it's first treated
// as an integer.
long l = 1234567889;
要建立一个长期的,你可以添加L
到你的电话号码,所以602200000000000000000000L
,虽然会不适合长期或者 - the max value is 263-1。
要创建双,你可以添加.0
到你的电话号码,所以602200000000000000000000.0
(或6.022e23
为Guffa建议),但如果你想精确值,你不应该使用这个,因为你可能会失去的,因为它的方式一定的准确性存储该值。
要创建BigInteger
,你可以使用the constructor taking a string parameter:
new BigInteger("602200000000000000000000");
如果BigInteger说的太大,则必须安装更多的RAM。 – csmckelvey
问题可能不是BigInteger。该大小的整数可以用大约80位来表示。即使考虑到其他实现开销,BigInteger也会支持这一点,没有任何问题。问题可能是OP如何尝试初始化。 – Peter
将来,不要说“它仍然说它太大”,只需复制粘贴您看到的确切错误消息即可。对我来说编译器说'整数太大:602200000000000000000000'。 –