Java快速货币表示?

Java快速货币表示?,java,currency,long-integer,java-money,jsr354,Java,Currency,Long Integer,Java Money,Jsr354,我正在开发一个实时应用程序,它使用BigDecimal处理不同货币和汇率的货币,但是我面临一些严重的性能问题,我想更改底层表示 我一次又一次地读到,用Java表示货币的一种好的、快速的方法是使用长字符存储美分(或任何所需的精度)。正如其中一条评论所指出的,有一些LIB使用了包装器,比如FastMoney from 这里有两个问题 把钱作为长条(或装在包装袋里)储存起来,而把其他东西(如汇率)保持成倍,这样总是安全的吗?换句话说,如果我做Math.round(money*rate)(money是美

我正在开发一个实时应用程序,它使用BigDecimal处理不同货币和汇率的货币,但是我面临一些严重的性能问题,我想更改底层表示

我一次又一次地读到,用Java表示货币的一种好的、快速的方法是使用长字符存储美分(或任何所需的精度)。正如其中一条评论所指出的,有一些LIB使用了包装器,比如FastMoney from

这里有两个问题

  • 把钱作为长条(或装在包装袋里)储存起来,而把其他东西(如汇率)保持成倍,这样总是安全的吗?换句话说,如果我做
    Math.round(money*rate)
    (money是美分,rate是双精度的),我不会遇到与所有东西都是双精度的基本相同的问题吗

  • FastMoney和许多其他LIB只支持它们和基元类型之间的操作。如果我不能盈利,我该如何准确地表示投资的回报。除以(投资)(两者都是FastMoney)。我想我的想法是把两者都转换成双倍,然后再除以它们,但那是不准确的,对吗


  • 您正在寻找的功能已经在JavaMoney库中实现

    它有一个FastMoney类,可以执行
    long
    算法,这正是您所要求的

    对于新的Java开发人员-为什么是长的而不是双倍的?

    Java中的浮点算法由于其实现而导致一些意外的精度错误。因此,不建议在财务计算中使用

    还请注意,这与
    long
    算术计算中的精度损失不同,后者是由于分数部分未存储在long中。在执行过程中,可以通过将分数部分移动到另一个长的位置(例如1.05->1美元和5美分)来防止这种情况

    参考资料


  • 为什么要将货币金额相乘?你经常计算“50美元乘以2,75美元”吗?将金额存储为美分只需要您为显示进行格式化,您不需要任何库。@Kayaman您的意思是您不使用方形美元?@AndyTurner只有在我购买方形鸡蛋时才使用。我更喜欢自己。但是你需要大口袋。
    0.85
    不是货币金额,而是汇率。你为什么要把它储存在一个很长的时间里?我认为这是一个很好的答案。为了使用它,您仍然需要自己阅读规范。请注意,有一个基于大十进制的Money类和基于long的FastMoney类。我不确定是否要使用包装器(即FastMoney),它将创建成千上万个不必要的短期对象。除了类型安全之外还有什么好处?@Mattx Yes:你把代码的责任放在了库上,而不是你。此外,您还可以标准化代码,以便对开发人员隐藏操作,因为它可能是问题的根源。如今,短命物体的成本通常可以忽略不计。尝试使用实际的微基准测试来分析问题是否真的存在。“过早优化是万恶之源。”我曾计划使用long和带有静态方法的接口来隐藏操作的逻辑,我粘贴的代码只是一个例子,实际上它将变成Decimal.multiply(decimal1,decimal2)。无论如何,我会对FastMoney进行基准测试,并将其与大小数和长/双精度作为基准进行比较。在快速测试计算(1.0+0.25)*0.5百万次使用FastMoney(表示1.0和0.25)时,对于相同的任务,它被证明比大小数慢。不知道为什么。