Java : How to count the number of decimals contain

2019-06-07 06:15发布

问题:

For a change-making application, made with Java, I am facing a problem while counting the number of decimals in a double value.

The double value represent money, so all my operations must be made in consequences that a double value like 12.58 can be stored as 12.5797886 after an operation is made on the original value. To counter this effect, I chose to use String, just like this :

String amountString = String.valueOf(amount);
String decimals = amountString.substring(amountString.indexOf('.') + 1);

So if the amount is 12.58, I obtain 58 and not 57978...

My problem is concerning big amount, just like 12849561476651.2501535 A such amount is converted in scientific notation while stored in a double. So the double value of the amount would be 1.284956147665125E13

Unfortunately I can't just count the number after the dot and take everything after the position 13. In a situation just like this one, where the original decimals 2501535 contains a 0 at the third position, the result after the position 13 is rounded to 25.

I found some solution for people who want to print a decimal value without the scientific notation, they use .printf( %f , ... ) or something similar.

But, if it is possible, how can I count the number of decimals contained in a double value and take care of the storage problem and the scientific notation?

I must be able to know if there is more than 2 decimals. In addition, if you have a pretty performant solution, even if it is a complex or a strange one, it would be great.

Thank you

回答1:

Do not use double or float to store currency, or to store any decimal numbers that need to be exact, as double and float can be inaccurate.

You can use BigDecimal or else use an int or a long and keep track of the decimal point yourself.

For more info on this, see the section "Item 48: Avoid float and double if exact answers are required" in Effective Java by Joshua Bloch: http://uet.vnu.edu.vn/~chauttm/e-books/java/Effective.Java.2nd.Edition.May.2008.3000th.Release.pdf



回答2:

Don't use a float or double for financial operations. It is better to use a BigDecimal. A BigDecimal give you the precision that you need. From the javadoc:

arbitrary-precision signed decimal numbers

The double will generate errors due to the approximation of the internal binary representation of doubles. Also for very small values it can generate errors that are very difficult to find.



回答3:

You can't. Floating point doesn't have decimal places. It has binary places, and they are not commensurable with decimal places. If you want decimal places you must use a decimal radix.

Use BigDecimal.

EDIT In a paragraph that you added since this answer and which you have now deleted, you state that the number comes from the UI. In which case it is a String at that point, which is already in radix-10, so you should just be counting decimal places in the String, and not converting it to a double at all.