13

Why does the code below throw a java number format exception?

BigDecimal d = new BigDecimal("10934,375");
The amateur programmer
  • 1,238
  • 3
  • 18
  • 38

3 Answers3

15

Yes, the BigDecimal class does not take any Locale into account in its constructor that takes a String, as can be read in the Javadoc of this constructor:

the fraction consists of a decimal point followed by zero or more decimal digits.

If you want to parse according to a different Locale, one that uses the comma as decimals separator, you need to use java.text.DecimalFormat with a specific Locale.

Example:

DecimalFormat fmt = new DecimalFormat("0.0", new DecimalFormatSymbols(Locale.GERMAN));
fmt.setParseBigDecimal(true);
BigDecimal n = (BigDecimal) fmt.parse("10934,375");

Note: you need to get an instance of DecimalFormat (a subclass of NumberFormat) to be able to call the method setParseBigDecimal. Otherwise it returns a Double instead, which is a binary floating point number, and binary floating point numbers cannot accurately represent many decimal fractions. So that would cause a loss of accuracy in many cases.

Community
  • 1
  • 1
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
9

The problem is that constructor of BigDecimal requires decimal number format where decimals come right after decimal dot . instead of decimal comma , so the right format for this specific case would be:

BigDecimal d = new BigDecimal("10934.375");
The amateur programmer
  • 1,238
  • 3
  • 18
  • 38
  • 2
    Great, you asked the question and answered it instantly. Why is that so? – Keerthivasan Mar 17 '14 at 12:24
  • 4
    To share information maybe? It took me pretty long to resolve the problem in my code. – The amateur programmer Mar 17 '14 at 12:25
  • 3
    @Octopus: [self-answering a question](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/) [is encouraged](http://meta.stackexchange.com/questions/2706/posting-and-answering-questions-you-have-already-found-the-answer-to?rq=1). – Jeroen Vannevel Mar 17 '14 at 12:26
  • 1
    That's very nice to hear :) You got my upvote for your question and answer. I also learnt that *German Locale uses comma for decimal points instead of dot* – Keerthivasan Mar 17 '14 at 12:54
  • @Octopus Most European countries do, except for the Brits. My own country doesn't have a constant in Locale. Examples: http://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html – Erwin Bolwidt Mar 17 '14 at 14:36
  • @ErwinBolwidt Thanks for the link, Cheers! BTW, which is your country? – Keerthivasan Mar 17 '14 at 14:52
3

You can use NumberFormat to choose the Locale, see the example:

        String numberToFormat = "1.900,35";
        NumberFormat formatter = NumberFormat.getNumberInstance(Locale.GERMAN);
        Number number = formatter.parse(numberToFormat);
        BigDecimal decimal = BigDecimal.valueOf(number.doubleValue());
Raul Guiu
  • 2,374
  • 22
  • 37