Mathcontext needed for add, subtract and multiply? [duplicate] - java

This question already has answers here:
Use of java.math.MathContext
(5 answers)
Closed 7 years ago.
first of, my search skills may be not as good as I hoped, so maybe this kind of question exists already. If so please tell me..
See this code below:
new BigDecimal("5").add(new BigDecimal("7"));
vs
new BigDecimal("5").add(new BigDecimal("7"), mathContext);
In which situations would I really need a mathcontext (except divisions)?
I never use a mathcontext unless I divide something. As far as I know this always worked, so what may be the drawbacks here? Do I need a mathcontext on add, subtract and multiply? I'm not so good into the BigDecimal, I simply want to use it to not lose any information like when using doubles.
As I sometimes see code with mathcontext on adding something, I'm too afraid to just remove it only because it's my opinion that it is useless...
I read that question but didn't really find a proper answer to my specific question...
I begin with BigDecimals without mathcontext and then calculate with them. So my question is, will I ever have drawbacks with this regarding information loss / precision etc? Or will this simply lead to maximum information and that's it?
Edit: I don't want to round, never. In cases of a division like 1/3 I would have to, of course, but in the cases of add, multiply and subtract I don't want any rounding. Do I then need a mathcontext in any circumstance?

If you are doing mathematical operations, that need rounding.
If you add, subtract or multiply two numbers with some decimal parts and you would like to round the result, you also can use mathcontext.
If you don't need to round anything, then you don't need it.
So it is not only limited to avoid problems with endless rest from dividing like 1/3

I could imagine a case where you want the result to be rounded while de operands are not. An example for addition.
1.23 + 3.01 = 4.24
So, maybe you want your result to have just decimal place, so you would use a MathContext to make it
1.23 + 3.01 = 4.2
I have no idea for a real world example but I think it's immaginable they exist.

Related

How to round doubles to a specified decimal place without Libraries?

Basically I'm supposed to write a method, that uses a double "x" and an int "y" and rounds (>=5 upwards, <5 downwards) "x" to the decimal place specified by y (between 1-8). The method is supposed to return a double. However since I just started I don't have a clue how to achieve this. The exercise prior to this one way easier.
If read answers to similar question but they are not quit what I need, because I can't use the Math library or other libraries. I'm allowed to make auxiliary methods to substitute this.
Rounding like that with double isn't going to work. Doubles and floats are represented with a fixed number of bits of data, and work in binary not decimal. That means that some numbers can't be represented. .1 can't be stored exactly.
In order to do this, you need to do use BigDecimal, which is a class that can store any exact number. Math using BigDecimal is less efficient, but it doesn't have the accuracy issues of doubles.

Java - Which data type for physical calculations?

I'm trying to create a physical calculation program in Java. Therefore I used some formulas, but they always returned a wrong value. I split them and and found: (I used long so far.)
8 * 830584000 = -1945262592
which is obviously wrong. There are fractions and very high numbers in the formulas, such as 6.095E23 and 4.218E-10 for example.
So what datatype would fit best to get a correct result?
Unless you have a very good reason not to, double is the best type for physical calculations. It was good enough for the wormhole modelling in the film Interstellar so, dare I say it, is probably good enough for you. Note well though that, as a rough guide, it only gives you only 15 decimal significant figures of precision.
But you need to help the Java compiler:
Write 8.0 * 830584000 for that expression to be evaluated in double precision. 8.0 is a double literal and causes the other arguments to be promoted to a similar type.
Currently you are using integer arithmetic, and are observing wrap-around effects.
Reference: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
If you need perfect accuracy for large decimal numbers, BigDecimal is the way to go, though it will be at the cost of performance. If you know you numbers are not that large, you can use long instead which should be faster, but has a much more limited range and will require you to convert from and to decimal numbers.
As physics calculations involves a lot of floating point operations, float data type can be a good option in such calculations. I Hope it will help. :)

How do You Find the Number of Places After the Decimal Point with BigDecimal?

I'm trying to use BigDecimals to calculate something and then round to 5 decimal places if it has more than that. How can I do this?
Would scale() work?
Did you already crawl through JavaDoc, especially the function precision()?
And this here might be a direct solution which makes it needless to check the precision first:
yournumber.round(new MathContext(5, HALF_UP));
And after that use stripTrailingZeros() (thx to #GregKopff)

Java best type to hold price [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Representing Monetary Values in Java
which java type is good to handle price value? and please tell my why ?
I dont know it is simply question :)
I only know that this type must be "safe". Because if we create shop applicatoion or somethink like that.
ps. I need BEST PRACTICE
and how it present in database ?
you should use BigDecimal when dealing with currencies. Java's native floating point types suffer from the same precision issues as other languages, since some decimals cannot be accurately represented as floating point numbers. Even thought it's not java specific, this is an excellent article which describes the complexities around representing decimal values as floating point numbers.
In general, transient values in your application should always use BigDecimal, only converting to a float when you must (for persistence, or displaying data to a user, etc).
an integer (or long) for the smallest denomenator you care about (cents for USD and EUR)
this is because floating points on computers are inherently inaccurate for decimal values(0.1+0.2 != 0.3)
you only need to translate between cent and main dollar in the UI while the domain calculates everything in cents
Personally, I would use BigDecimal (and so does my company!). I consider float or double bad suggestions because of the way floating-point values are stored in the system and there is a possibility of loss of precision (which you certainly don't want when handling money).
If you're building a financial system, I recommend you create or use your own Java class to represent monetary amounts.
As far as the data type to use to hold a monetary amount, long or BigDecimal.
Here's an example Money class that shows the types of methods you need when working with monetary amounts.
If you use sensible rounding of your results double is works perfectly well and not only the fastest but the simplest to write. This can represent money up to $70 trillion without error. Don't use float as this can only represent up to about $10,000 without error.
If you don't know what sensible rounding to use, BigDecimal or long cents could be a better choice.
You need to use the BigDecimal class.

Bigdecimal for financial calculations and non-terminating computations

I'm sure this would be a simple question to answer but I can't for the life of me decide what has to be done. So here's it: assuming we follow the "best practice" of using BigDecimal for financial calculations, how can one handle stuff (computations) which throw an exception?
As as example: suppose, I have to split a "user amount" for investing in bonds between "n" different entities. Now consider the case of user submitting $100 for investing to be split between 3 bonds. The equivalent code would look like:
public static void main(String[] args) throws Exception {
BigDecimal bd1 = new BigDecimal("100.0");
BigDecimal bd2 = new BigDecimal("3");
System.out.println(bd1.divide(bd2));
}
But as we all know, this particular code snippet would throw an ArithmeticException since the division is non-terminating. How does one handle such scenarios in their code when using infinite precision data types during computations?
TIA,
sasuke
UPDATE: Given that RoundingMode would help remedy this issue, the next question is, why is 100.0/3 not 33.33 instead of 33.3? Wouldn't 33.33 be a "more" accurate answer as in you expect 33 cents instead of 30? Is there any way wherein I can tweak this?
The answer is to use one of the BigDecimal.divide() methods which specify a RoundingMode.
For example, the following uses the rounding mode half even or bankers rounding (but half up or one of the other rounding modes may be more appropriate depending on requirements) and will round to 2 decimal places:
bd1.divide(bd2, 2, RoundingMode.HALF_EVEN);
divide has an overload that takes a rounding mode. You need to choose one. I believe "half even" is the most commonly used one for monetary calculations.
bd1.divide(bd2, 5, BigDecimal.ROUND_FLOOR)
It's an exemple, depending on the rounding you want.

Categories