2

Why is there a BigDecimal.setScale() method which sets the decimals to some value and no MathContext.setScale() method but only a constructor MathContext(precision) or other way around why is there no BigDecimal.setPrecision() method?

EDIT: There is no method MathContext.setPrecision(), only a constructor MathContext(precision). Edited the text. Sorry for that.

EDIT2: I just wanted to understand why there are two ways of approaching a scale / precision setting. Seems there is no real reason to have two of them regarding the answer of Richard Sitze.

See this example which makes clear you can really have strange results playign with precision and scale:

MathContext mc = new MathContext(2);
BigDecimal test = new BigDecimal("100.234", mc);
System.out.println("Scale: " + test.scale() + ", value: " + test);
test.setScale(6);
System.out.println("Scale: " + test.scale() + ", value: " + test);
test = test.add(new BigDecimal("100"));
System.out.println("Scale: " + test.scale() + ", value: " + test);

Results in:

Scale: -1, value: 1.0E+2
Scale: -1, value: 1.0E+2
Scale: 0, value: 200

The results are correct regarding the settings but when I set the scale to 6 I expect a warning / hint / exception which says that the precision settings do not allow a scale of 6.

4thfloorstudios
  • 388
  • 1
  • 6
  • 16
  • 4
    You'll have to ask whoever wrote `BigDecimal`. – arshajii Aug 07 '13 at 15:47
  • 1
    What particular problem are you trying to solve by asking this question? – Colin D Aug 07 '13 at 15:50
  • @SteveP. The precision can be set as a MathContext constructor argument. A MathContext is immutable, so no setXXX methods at all. – Patricia Shanahan Aug 07 '13 at 15:52
  • @Steve P: You are right Steve, you can only pass the precision in the constructor but the problem remains the same :) – 4thfloorstudios Aug 07 '13 at 15:53
  • @4thfloorstudios What problem? There is no problem. – Steve P. Aug 07 '13 at 15:55
  • 1
    Because [`BigDecimal`](http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html) is immutable. – Mark Rotteveel Aug 07 '13 at 15:56
  • @ColinD: I want to be able to create a MathContext to pass to a BigDecimal and I wondered what happens if i pass a MathContext with precision 3 and scale value of 10 to the constructor `BigDecimal(BigInteger unscaledVal, int scale, MathContext mc)` The question is related to [this](http://stackoverflow.com/questions/18107162/maximum-precision-below-unlimited) – 4thfloorstudios Aug 07 '13 at 15:57
  • Can't you use [`round(MathContext mc)`](http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#round(java.math.MathContext)) – Mark Rotteveel Aug 07 '13 at 15:58
  • @4thfloorstudios You should include all of that in your question. As is, your questions looks like you are asking about designer choices which is off topic. – Colin D Aug 07 '13 at 15:59
  • @4thfloorstudios If that was actually your question, then you shouldn't have asked the question that you did. See the [XY-Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Additionally, these are two completely different questions. One is somewhat subjective, and potentially closeable, and the other is clearly acceptable, and much more likely to get you the answer that you actually want. – Steve P. Aug 07 '13 at 15:59
  • @all: I must apologize for the way I asked the question. If you take a look at [this](http://stackoverflow.com/questions/18107162/maximum-precision-below-unlimited) you will understand what I mean (hopefully). – 4thfloorstudios Aug 07 '13 at 16:01
  • Honestly, from the comments, I'm still a little confused about your confusion. I suggest that you create an entirely new question that details exactly what you're trying to do in words, and with accompanying code. – Steve P. Aug 07 '13 at 16:06
  • @SteveP: Will do that, thanks for your time! – 4thfloorstudios Aug 07 '13 at 16:11
  • @4thfloorstudios Also, it's a good idea to reference other posts in your question, if applicable. It helps people to understand your problem, and lowers the possibility of it being closed as a duplicate if the questions are related. – Steve P. Aug 07 '13 at 16:14

2 Answers2

3

There is no method MathContext.setPrecision(), only a non-static getPrecision(). The constructor for MathContextis what is used to set the precision.

If you refer to the documentation of BigDecimal, we have:

The BigDecimal class gives its user complete control over rounding behavior. If no rounding mode is specified and the exact result cannot be represented, an exception is thrown; otherwise, calculations can be carried out to a chosen precision and rounding mode by supplying an appropriate MathContext object to the operation.

Essentially, there's no reason to recreate the wheel--MathContext already does this, by design.

Steve P.
  • 14,489
  • 8
  • 42
  • 72
2

The powers-that-be declared that the overall precision (total # of digits) can be adjusted only incidentally by changing the scale (# of digits to the right of the decimal point).

This is appropriate, as any change to precision necessitates a change to scale. So at best setPrecision is redundant; having only setScale has resulted in a cleaner API.

Now consider a change to precision and how the result might need to be rounded. In going through that analysis, you will consider "how many digits should remain after rounding". That is the scale. Thus any such consideration leads back to the question of how the scale should be changed.

setScale with its variants to specify rounding are a natural fit. Less so for a hypothetical setPrecision, which begs for code comments to fill the gap (IMHO).

Steve P.
  • 14,489
  • 8
  • 42
  • 72
Richard Sitze
  • 8,262
  • 3
  • 36
  • 48