Parsing "1,2,3" using the en-US's decimal format results in the number 123.
import java.text.*;
import java.util.Locale;
public class Main{
public static void main(String[] args) throws ParseException {
final String text = "1,2,3";
final int weirdResult = 123;
final NumberFormat usDecimalFormat = DecimalFormat.getNumberInstance(Locale.US);
final Number parsedNumber = usDecimalFormat.parse(text);
if(parsedNumber.doubleValue() == weirdResult){
System.out.println(text + " is bizarrely parsed as " + weirdResult);
} else {
System.out.println(text + " is parsed as " + parsedNumber);
}
}
}
The above code actually prints 1,2,3 is bizarrely parsed as 123.
How is "1,2,3" a valid number and why its value is 123?
DecimalFormathas an internal method,#subparse, which takes care of interpreting separators and other special characters (dependent on theLocalethat you have passed in). It will track the characters of interest (like digits, the decimal separator, or currency symbols), but of particular interest is how "grouping separators" (e.g.,in UK,.in France) are handled when doing this parse:Source: DecimalFormat.java:2290 (Note: The above was refactored into
#subparseNumberas of JDK 12)Note the
breakmeans to finish parsing the number, and the lack of appending todigitListmeans they effectively ignore these grouping separators. Further, the ignoring of these grouping separators is not dependent on how many digits have been parsed since the last separator. The only conditional based on previous separators is if the grouping separator appears after the decimal separator, hence thebreak.