【问题标题】:MathContext.DECIMAL32 vs MathContext.DECIMAL64, which one to use, and why?MathContext.DECIMAL32 vs MathContext.DECIMAL64,使用哪一个,为什么?
【发布时间】:2017-01-07 20:34:37
【问题描述】:

我应该使用MathContext.DECIMAL32 还是MathContext.DECIMAL64?我看过documentation,但我也不太明白什么时候使用。

我使用 BigDecimal 来表示我想应用于一定金额的百分比。像这样的:

...
final MathContext mc = MathContext.DECIMAL32;
BigDecimal amount = getAmount(args);
float percent = getPercent().floatValue();
BigDecimal percentAsBd = new BigDecimal(percent/100.f, mc).setScale(4, RoundingMode.HALF_UP);
BigDecimal threshold = amount.multiply(percentAsBd);
...

我正在使用 oracle java 1.8、ubuntu 14.04、Intel core i7 (64bit)

【问题讨论】:

  • 任何你觉得你应该使用其中一个的特殊原因,而不是构造一个符合你要求的 MathContext,例如四舍五入?
  • @PatriciaShanahan 我想我担心它与我认为是 32 位的 java 的本机浮点数的兼容性。
  • Java 的原生浮点数是基于二进制的,而不是十进制的,并且比 BigDecimal 更不适合表示百分比。我认为它的大小无关紧要。
  • @PatriciaShanahan;我认为DECIMAL32 和DECIMAL64 上下文的精度分别或多或少与float 和double 匹配,并确保BigDecimal 不必使用BigInteger。
  • @has981:如果可以避免的话,不要将float 或double 与BigDecimal 混合使用。您应该使用BigDecimal 来获得它提供的精度,而floats 和doubles 从未如此精确。而是直接用字符串初始化BigDecimals,或者longs。

标签: java floating-point bigdecimal mathcontext


【解决方案1】:

根据您的系统架构,如果您不在 x64 芯片组上,则任何 64 位类型操作的指令集都将分散到两个 CPU 上。使用您的英特尔酷睿 i7 (x64) 可以解决任何与此相关的问题。

更新日期:2016 年 1 月 9 日

根据 JVM 规范,对任何 64 位值的赋值都需要两个 32 位的赋值。

public class IdGenerator {
  private long id;
  public IdGenerator() {
    id = 0;
  }
  public int getNextId() {
    ++value;
  }
}

基于该假设,上述对 getNextId 的调用不是原子的。如果在多线程上下文中使用此类,则结果 getNextId() 可能不完全准确,例如这些调用可能会产生以下 ids 0,1,3,5,6,7,8,10。在 x86 平台上使用 32 位类型不会出现这种行为。

2016 年 5 月 9 日更新

希望以下链接对我的回答有所帮助

http://preshing.com/20130618/atomic-vs-non-atomic-operations/

【讨论】:

  • 嗯?老实说,我想我现在明白了,但你是什么意思?你能举个例子吗?什么“指令集将在两个 CPU 上拆分”?你的意思是说,在 32 位系统中,有两个 CPU 具有不同但互补的指令集?
  • 我也很困惑。在没有 64 位内存操作的处理器上,64 位加载被实现为两个 32 位加载,这是一个真正的问题。据我所知,它与跨 CPU 分割指令集无关。
  • @PatriciaShanahan:ISTM 认为,对于“指令集”,Jim 的含义与通常的含义完全不同。
  • 请注意,++value 即使在 64 位处理器上也不是原子的。您需要将对value 的访问限制为单个线程,这使得非原子行为无法通过正常方式观察到,或者以其他方式保护它。
  • @RudyVelthuis 你可能是对的,但这让我无法理解这个答案的第一段。
猜你喜欢
  • 2012-08-20
  • 2013-05-19
  • 2012-02-15
  • 1970-01-01
  • 2021-02-06
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
相关资源
最近更新 更多