Java 使用正确的数字数据类型

Java 使用正确的数字数据类型,java,types,numbers,Java,Types,Numbers,在更多地参与培训新工程师以及阅读之后,我开始认识到许多工程师不清楚何时使用哪些数字数据类型。我很欣赏一个正式的计算机科学学位在这方面所起的作用,但我看到很多新的工程师表现出不确定性,因为他们从未处理过大型数据集、金融软件、编程物理或统计问题,或复杂的数据存储问题 我的经验是,当人们在上下文中解释概念时,他们真的会感到恶心。我正在寻找真实编程问题的好例子,其中某些数据最好使用数据类型来表示。如果可能的话,尽量远离课本上的例子。我正在用Java为其添加标签,但请随意给出其他语言的示例并重新标记: 整

在更多地参与培训新工程师以及阅读之后,我开始认识到许多工程师不清楚何时使用哪些数字数据类型。我很欣赏一个正式的计算机科学学位在这方面所起的作用,但我看到很多新的工程师表现出不确定性,因为他们从未处理过大型数据集、金融软件、编程物理或统计问题,或复杂的数据存储问题

我的经验是,当人们在上下文中解释概念时,他们真的会感到恶心。我正在寻找真实编程问题的好例子,其中某些数据最好使用数据类型来表示。如果可能的话,尽量远离课本上的例子。我正在用Java为其添加标签,但请随意给出其他语言的示例并重新标记:


整数、Long、Double、Float、BigInteger等。

BigDecimal是维护精确浮点计算并能够指定所需精度的最佳选择。我相信float(在某种程度上是double)比BigDecimal提供了性能优势,但代价是准确性和可用性。

我真的认为您不需要示例或任何复杂的东西。这很简单:

  • 是整数吗?
    • 它能大于2^63吗?大整数
    • 它能大于2^31吗?长的
    • 否则int
  • 是十进制数吗?
    • 近似值可以吗?
      • 双重的
    • 需要精确吗?(例如:货币金额!)
      • 大十进制
(我说“>”,当然是指“绝对值更大”)

我从来没有用过字节或字符来表示数字,也从来没有用过短句号。这是12年的Java编程。浮动无聊的。如果你有一个巨大的数组,你有内存问题,我猜


请注意,BigDecimal有点命名错误;您的值不必太大就可以使用它。

如果我们谈论的是独立于机器的(32/64位)数据类型大小,则通常为数字,如下所示:

整数:4字节

长:8字节

十进制/浮点:4字节

双字节:8字节

有符号值的大小减少到一半(例如:对于4字节,无符号=40亿,有符号=20亿)

bigInt(取决于语言实现)有时高达10字节

对于大容量数据归档(如搜索引擎),我强烈建议使用byte和short来节省空间

字节:1字节,(0-256无符号,-128-128有符号)

短:2字节(65k无符号)



假设您想保存关于年龄的记录,因为没有人活到150岁以上,所以您使用了数据类型BYTE(读取上面的大小)但是,如果你使用整数,你已经浪费了额外的3字节,并认真地告诉我它的寿命超过40亿年。

一个重要的一点,你可能想阐明的是,比较浮点数是否相等几乎总是一个错误。例如,以下代码很可能失败:

double euros = convertToEuros(item.getCostInDollars());
if (euros == 10.0) {
  // this line will most likely never be reached
}
这是您希望使用离散数字表示货币的众多原因之一

当您绝对必须比较浮点数时,您只能近似地进行比较;在某种程度上:

double euros = convertToEuros(item.getCostInDollars());
if (Math.abs(euros - 10.0) < EPSILON) {
  // this might work
}
double euros=convertToEuros(item.getCostInDollars());
如果(算术平均值(欧元-10.0)
至于实际例子,我通常的经验法则是这样的:

  • 双重:在使用它之前要仔细思考;这种痛苦值得吗
  • 浮子:不要用它
  • byte:最常用作byte[]来表示一些原始二进制数据
  • int:这是你最好的朋友;用它来表示大多数东西
  • long:用于时间戳和数据库ID
  • BigDecimal和BigInteger:如果你知道这些,很可能你已经知道你在做什么,所以你不需要我的建议

我意识到这些并不是非常科学的经验法则,但如果你的目标受众不是计算机科学家,那么最好还是坚持基本原则。

Lucene中的VInt's's are the devil。一个字节一个字节地读取它们的性能损失大大超过了大小上的小好处


讨论空间与时间的权衡是一件好事。在1996年节省200mb是很好的,但在2010年,一次读取一个字节的IO缓冲区就太糟糕了。

我不太喜欢你的示例代码,因为你不应该一开始就使用double作为货币数据。您应该使用BigDecimal。参见《有效的Java》(第二版)一书中的第48项。Jonik——他向我们展示了为什么双人是不好的。他说,“如果你必须使用浮点运算,那么这里有一些方法。”。这里没有犯规。顺便说一句,我认为这是一个很好的回答,至少和我的一样好。唯一的例外是,BigDecimal确实应该被作为精确处理十进制数的唯一方法来提倡;不仅仅是“哦,你可能知道你在做什么…”凯文-嗯,是的,但答案并不十分清楚,尤其是当没有一个字表明BigDecimal是正确的方法时!这样的例子最好作为附录,例如你自己的答案,它更清楚地列出了基本的经验法则(正如选民们所同意的)我真的很喜欢你把它分解的方式。100%同意您在Java中使用char、short和float。另外一个提示:如果它是一个十进制数,并且需要精确,但小数位数的最大位数是预先知道的(例如$values:2 dec.places),那么您可以使用int/long,并在输出时进行除法。这避免了BitDecimal的问题(性能,笨拙的操作员)。过早优化的典型例子…除非你正在保存一个庞大的数组或数据库,否则请使用INT。如果大小不是问题(在大多数现代情况下不是),那么没有任何负面影响,而正面影响是你不会因为prem而落入像Y2K这样愚蠢的错误