1

Should I use MathContext.DECIMAL32 or MathContext.DECIMAL64? I have looked at the documentation, but I couldn't really understand when to use either.

I'm using BigDecimal to represent a percentage that I want to apply to an amount of money. Something like this:

...
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);
...

I'm using oracle java 1.8, ubuntu 14.04, Intel core i7 (64bit)

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
has981
  • 425
  • 4
  • 18
  • 2
    Any particular reason you feel you should use one of them, rather than constructing a MathContext that fits your requirements for e.g. rounding? – Patricia Shanahan Aug 31 '16 at 10:04
  • @PatriciaShanahan I guess I'm concerned regarding its compatibility with java's native float which I assume is 32bits. – has981 Aug 31 '16 at 10:13
  • Java's native float is binary based, not decimal, and is much less suitable than BigDecimal for representing percentages. I don't think its size is relevant. – Patricia Shanahan Aug 31 '16 at 13:51
  • @PatriciaShanahan; I think the `DECIMAL32` and `DECIMAL64` contexts have precisions that more or less match those of `float` and `double` respectively, and ensure that the BigDecimal doesn't have to use BigInteger. – Rudy Velthuis Aug 31 '16 at 21:19
  • Thanks @RudyVelthuis, If I understand you correctly, the choice has nothing to do with my HW architecture, and is all about the precision. I haven't had any issues so far with passing float and DECIMAL64 to BigDecimal constructer (e.g.: `new BigDecimal(1.f, MathContext.DECIMAL64)`) but given your input regarding precision, I think it makes more sense to pass DECIMAL32 along with floats. Please correct me if I'm wrong. – has981 Sep 01 '16 at 07:08
  • 1
    @has981: Don't mix the use of `float` or `double` with the use of `BigDecimal`, if you can avoid it. You should use `BigDecimal` for the precision it provides, and `floats` and `doubles` are never so precise. Rather initialize `BigDecimals` directly with strings, or `long`s. – Rudy Velthuis Sep 01 '16 at 15:48

1 Answers1

0

Depending upon your system's architecture, the instruction set for any 64 bit type operation will be split across two CPUs if you aren't on a x64 chipset. With your Intel core i7 (x64) any issues around this are negated.

Updated: 01/09/2016

According to JVM specifications assignment to any 64-bit value assignment requires two 32-bit assignments.

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

Based on that assumption the above call to getNextId is not atomic. If this class is used in a multiple thread context, the result getNextId() may not be fully accurate e.g. these calls may produce the following ids 0,1,3,5,6,7,8,10. You would not get this behaviour with a 32-bit type on an x86 platform.

Update 5/9/2016

Hopefully the following link will help with my answer

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

James McGuigan
  • 107
  • 1
  • 6
  • 1
    Huh? Honestly, I think I understood things nowadays, but what do you mean? Could you give an example? What "instruction set will be split across two CPUs"? You mean that, say, in 32 bit systems, there are two CPUs that have different but complementary instruction sets? – Rudy Velthuis Aug 31 '16 at 20:40
  • I am also confused. There is a real issue of 64-bit loads being implemented as two 32-bit loads on processors that do not have 64-bit memory operations. As far as I know, it has nothing to do with splitting the instruction set across CPUs. – Patricia Shanahan Aug 31 '16 at 22:51
  • @PatriciaShanahan: ISTM that, with "instruction set", Jim means something totally different than what is usually meant with it. – Rudy Velthuis Sep 01 '16 at 15:51
  • Note that `++value` is not atomic even on a 64-bit processor. You need to either limit access to `value` to a single thread, which makes non-atomic behavior impossible to observe by normal means, or otherwise protect it. – Patricia Shanahan Sep 01 '16 at 16:02
  • @RudyVelthuis You are probably right, but it gets me no closer to understanding the first paragraph of this answer. – Patricia Shanahan Sep 01 '16 at 16:03