2

I want to convert the number "4,471.26" into decimal number "4471.26".

Actually number "4,471.26" is received as String and for further process, need to convert it into Decimal number.

"4,471.26" - is just a format,so value is keeps changing every-time. This value could be anything like "654,654,25.54"

Tried by considering comma (,) as group -separator. But looks like has different ASCII values.

String Tempholder = "4,471.26";
Decimal.valueOf(Tempholder.replaceAll(getGroupSeparator(), ""));



  private char getGroupSeparator() {
            DecimalFormat decFormat = new DecimalFormat();
            DecimalFormatSymbols decSymbols = decFormat.getDecimalFormatSymbols();
            return Character.valueOf(decSymbols.getGroupingSeparator());
        }

Below code would be temporary solution, but it will not work other geo regions.

String Tempholder = "4,471.26";
Decimal.valueOf(Tempholder.replaceAll(",", ""));

Kindly help ..

Rama
  • 815
  • 2
  • 17
  • 37
  • 1
    can't you just .replace() all the "," with nothing, and parse that as a double? – sleepToken Dec 04 '19 at 13:37
  • 1
    Simply use `replace` and then the BigDecimal constructor that takes in a String. – Amongalen Dec 04 '19 at 13:43
  • Thanks for reply, but that not work with other geo regions – Rama Dec 04 '19 at 13:45
  • I think he means that in some regions it's common to use , instead of . to signify decimals. – Astrogat Dec 04 '19 at 13:46
  • 1
    Not really a duplicate, but answers to [this question](https://stackoverflow.com/questions/888088/how-do-i-convert-a-string-to-double-in-java-using-a-specific-locale) may help. – Federico klez Culloca Dec 04 '19 at 13:47
  • that's correct Astrogat , I am looking for solution which could work for all regions – Rama Dec 04 '19 at 13:47
  • Federico klez Culloca, thanks for reply, but the number contains both , group separator and decimal separator whereas your refer link only talks about the string which contains decimal separator – Rama Dec 04 '19 at 13:51
  • Is there *always* a decimal part in your numbers or can they be integers (like "1,234" as in "one thousand two hundred thirty-four")? (also, protip: put a `@` before a username, as in @user3302083, when answering to someone in comments, they'll receive a notification) – Federico klez Culloca Dec 04 '19 at 14:02
  • 1
    @FedericoklezCulloca and/or are there _always_ 2 decimals when there are decimals? – Thomas Timbul Dec 04 '19 at 15:14

4 Answers4

0

you can do it like this :

public class JavaCodes{
public static void main(String[] args) {
    String str = new String("4,233.19");
    str = str.replaceFirst(",", "");
    System.out.println(Double.valueOf(str));
  }
}
Himanshu Singh
  • 2,117
  • 1
  • 5
  • 15
  • OP's problem seems to be that it has to work for other locales too. For example, in Italy that number would look like `4.233,19`, and your answer doesn't account for that. – Federico klez Culloca Dec 04 '19 at 13:58
0

Ok, some assumptions first

  • You don't know the locale beforehand
  • If just one separator is found, and it appears only once, we treat it as a decimal separator (for simplicity)
  • If just one separator is found but it appears multiple times, it's a thousands separator
  • Any non-digit character is a valid separator
  • If there are more than two non-digit characters in a string, that's an error.

So here's the algorithm

  • Find the first non-digit character and temporarily consider it a decimal separator
  • If another non-digit character is found
    • If it's the same as the decimal separator, and we still don't have a thousands seprator, make that the thousands separator and reset the decimal separator
    • If it's the same as the decimal separator, and we already have a thousands separator, that's an error
    • If it's not the same as the decimal separator, it's the thousands separator
  • Remove from the original string all occurrences of the thousands separator (if present)
  • Substitute the decimal separator with a dot
  • Parse as double.

And here is the code.

public class Test {

    public static double parseNumber(String x) {
        Character thousandsSeparator = null;
        Character decimalSeparator = null;

        for (int i = 0; i < x.length(); i++) {
            if (!Character.isDigit(x.charAt(i))) {
                if (decimalSeparator == null) {
                    decimalSeparator = x.charAt(i);
                } else {
                    if (decimalSeparator.equals(x.charAt(i))) {
                        if (thousandsSeparator == null) {
                            thousandsSeparator = x.charAt(i);
                            decimalSeparator = null;
                        } else {
                            if (!thousandsSeparator.equals(x.charAt(i))) {
                                throw new IllegalArgumentException();
                            }
                        }
                    } else {
                        thousandsSeparator = x.charAt(i);
                    }
                }
            }
        }

        // remove thousands separator
        if (thousandsSeparator != null) {
            int formerSeparatorPosition;
            while ((formerSeparatorPosition = x.indexOf(thousandsSeparator)) != -1) {
                x = x.substring(0, formerSeparatorPosition) + x.substring(formerSeparatorPosition + 1);
            }
        }

        // replace decimal separator with a dot
        if (decimalSeparator != null) {
            x = x.replace(decimalSeparator, '.');
        }
        return Double.parseDouble(x);

    }

    public static void main(String args[]) {
        System.out.println(parseNumber("123.45"));
        System.out.println(parseNumber("123,45"));
        System.out.println(parseNumber("1.234,5"));
        System.out.println(parseNumber("1,234.5"));
        System.out.println(parseNumber("1,234,567.512"));
        System.out.println(parseNumber("1.234.567,512"));
        ystem.out.println(parseNumber("1.234.567"));
        System.out.println(parseNumber("1_234_567|34")); // works with any two characters, if there are just two
        try {
            System.out.println(parseNumber("1_234_567|34,7")); // invalid
        } catch (IllegalArgumentException e) {
            System.out.println("Too many separators!");
        }
    }
}
Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
0

It is quite circumstantial to parse to a BigDecimal. To a double it is easier but floating point is just an approximation, and will loose the number's precision. 0.2 == 0.20 == 0.200 == (actually something like) 0.1999999987.

    String text = "4,471.26";
    DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
    format.setParseBigDecimal(true);
    BigDecimal number = (BigDecimal) format.parseObject(text);
    // number.scale() == 2

The US locale uses your desired separators.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
0

Thank you guys, for all your suggestion and helps. I figure out the below solution. Convert it into decimal number, And applicable to all geo region.

public static void geoSp() {
    String a = "4.233,19";
    NumberFormat as = NumberFormat.getInstance();
    double myNumber = 0;
    try {
        myNumber = as.parse(a).doubleValue();
    } catch (ParseException e) {
        e.printStackTrace();
    }
    System.out.println(String.valueOf(myNumber));
}

   gives  Out put :- 4233.19
Rama
  • 815
  • 2
  • 17
  • 37