Java - 物理计算使用哪种数据类型?

4

我正在尝试用Java创建一个物理计算程序。因此,我使用了一些公式,但它们总是返回错误的值。我将它们分解并发现:(到目前为止,我使用了long。)

8 * 830584000 = -1945262592

这显然是错误的。公式中涉及到分数和非常大的数字,例如6.095E23和4.218E-10。

那么,哪种数据类型最适合获得正确的结果呢?


3
或许是 BigDecimal? - Scary Wombat
1
你的问题并没有提供足够的信息。除了 doubleBigDecimal 外,还应该看一下 longBigInteger - C-Otto
除了信息不足之外,当我在Java中进行乘法运算(使用long)时,我得到的结果是:6644672000。 - Stultuske
1
你的乘法示例适用于“long”。看起来你仍在使用ints?对于有理数,请检查“Spire”或任何其他“数字数据类型”库。 - mgaert
1
你的常量是 int 字面量,而不是 long,所以计算会溢出。(即使你稍后将其分配给 long 变量;伤害已经造成。)如果你尝试 8L * 830584000L,你将得到正确的输出:6644672000。 - Ted Hopp
3个回答

3
除非你有非常充分的理由,否则在物理计算中使用double是最佳选择。它已经足够用于电影《星际穿越》中的虫洞建模,因此,我敢说,对于你来说可能也足够好了。请注意,它仅提供约15个十进制有效数字的精度作为大致指南。
但是您需要帮助Java编译器:
在表达式中写入8.0 * 830584000以便以double精度进行评估。8.0是一个double文字,并导致其他参数被提升为类似类型。
目前,您正在使用整数算术,并观察到环绕效应。
参考:https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

BigDecimal仍然是更好的选择。 - daniu
我之前尝试使用double,但结果也不正确,但是使用'X.0'这个方法却可以正常工作。 - Kinaeh
1
@Kinaeh 如果你做得正确,长时间的方式也完全可行。 - Stultuske
1
@Kinaeh:确实,8 * int 是一个 int 类型。你将其分配给 long 并不重要:从概念上讲,这发生在之后。 - Bathsheba
1
@Kinaeh:请原谅我,但我忍不住要说。在我看来,C++是物理计算中远远优秀的语言,其次是Fortran。如果你的前端需要使用Java,我会认真考虑用Java进行演示,并使用JNI将计算部分链接到C++(甚至是C)上。 - Bathsheba
显示剩余7条评论

2
如果您需要对大数进行完美的精度控制,BigDecimal 是首选,但这会以性能为代价。如果您知道您的数字不是那么大,您可以使用 long 来替代,这应该更快,但其范围更加有限,且需要从十进制数转换为整数。

0

由于物理计算涉及大量的浮点运算,因此在这种计算中使用浮点数据类型可能是一个不错的选择。希望这能有所帮助。:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接