【问题标题】:Using double to temporarily store currency values? [duplicate]使用 double 临时存储货币值? [复制]
【发布时间】:2015-01-12 19:14:13
【问题描述】:

很清楚为什么要使用 double & co。在处理货币方面不是一个好的选择。 不过我想知道,由于仅在对值执行计算时才会出现问题,因此我假设将货币值存储在 double 中完全没有问题,我是否正确?

例如: 1. 值从任何给定来源加载到双精度 2. 值被修改,由用户直接输入。 3. 值以合适的格式存储到磁盘。

在上面的示例中,double 只是一种将值存储在内存中的方法,因此如果对值执行计算,则不会出现任何问题。 这是正确的吗?

而且,如果正确,仅在执行计算时使用特定于货币的类型不是更好吗? 与其从数据库加载 1000 个 BigDecimal,不如加载 1000 个双精度数。然后,在必要时,定义一个 BigDecimal,进行计算并将生成的双精度值保留在内存中。

【问题讨论】:

  • 没有。当您将 double 转换为 BigDecimal 时,您将无法获得预期的价值。将货币存储在double 中会立即出错,因此如果您稍后要使用它进行计算,请不要这样做。当然,除非引入的错误与您的程序要求无关。
  • 如果您在转换为 BigDecimal 时足够小心并执行适当的舍入,并且您永远不需要超过 14 位有效数字,并且您始终知道要舍入到多少位,那么您的方法将是可行。不过,它仍然很脆弱。

标签: java double currency


【解决方案1】:

不,即使您不执行任何计算,它仍然会导致问题。问题是您存储的值可能无法完全表示为double,因此即使您只是将其存储并读回,也可能无法取回您存储的内容。

例如,如果您将 0.1 存储在 double 中,您会发现它实际上根本没有存储 0.1,因为您不能用二进制精确表示 0.1。

【讨论】:

  • 但是您可以舍入安全地回到 0.1。因此,如果您知道要四舍五入的精度,这可能会奏效。
  • @MarkoTopolnik 当然。我想这取决于确切的工作流程。即使它现在有效,它似乎是在为以后发生变化时存储麻烦。我不会碰它。
  • 没错,这就是我在对该问题的评论中所写的。有太多的如果让它得到回报。知道限制的确切位置仍然很好。
  • 你总是可以做new BigDecimal(Double.toString(myDouble)) 这应该是相当可靠的。
【解决方案2】:

没有。 double 永远不是存储货币值的正确类型。双精度数是浮点值,也就是说,它们基本上是 x * 2^y 形式的数字,其中 x 和 y 是整数。因此,某些值,例如 0.10(10 美分)没有精确的双精度表示。

【讨论】:

    【解决方案3】:

    这里的问题是,当您将 10.12 保存在 double 变量中时,它可能没有精确的双精度表示,因此 java 运行时会将其保存为最接近的可能双精度表示,例如 10.1199999999999 或 10.1200000000001(只是一个示例,我不确定,必须测试)。所以你明白了,只要你把这个值放在一个双变量中,货币值就会近似。但是,话虽如此,您仍然可以使用双精度数进行计算,然后在打印出值或写入文件时使用适当的格式,以便隐藏非有效数字,具体取决于您的应用程序。

    【讨论】:

    • 你选择了 10 1/8 作为你的例子,它是一个二进制整数。你本可以选择更好的:)
    • @MarkoTopolnik :) 谢谢,我会改的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多