2015-12-08 3 views
6
public class NumFormatTest 
{ 
    public static void main(String[] args) throws ParseException 
    { 
     String num = "1 201"; 
     DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRANCE); 
     System.out.println("Number Before parse: "+num);   
     double dm = df.parse(num).doubleValue(); 
     System.out.println("Number After parse: "+dm); 
    } 
} 

Выход:Java Десятичный формат синтаксический вопрос

Number Before parse: 1 201 

Number After parse: 1.0 

Ожидаемый результат:

Number Before parse: 1 201 

    Number After parse: **1201** 

Может ли пожалуйста, помогите мне понять, почему синтаксический анализ не в состоянии преобразовать ФРАНЦУЗСКИЙ локаль отформатированную строку (1 201) до нормального двойного значения (1201,0)?

+0

Я заметил, что-то вроде этого Если я первый попытаться отформатировать двойной как этот г = 1201 Строка RetVal = df.format (д); затем попытайтесь проанализировать это отформатированное значение, которое будет retVal = 1 201 double val = df.parse (retVal) .doubleValue(); Это будет работать и увидит val = 1201.0 Но у меня уже есть строка в формате FRENCH (1 201), и прямой синтаксический анализ не работает. Не знаю, почему ... если вы поможете мне ответить на эту причину. –

+0

Это может помочь: http://stackoverflow.com/a/8389625/3519951 –

+0

@AmitNag взгляните на мой ответ ... Я объясняю, что такое поведение – ParkerHalo

ответ

5

Есть два вида пространств. «Нормальный» космический символ (№ 32 - HEX 0x20) и неразрывное пространство (NBSP) (№ 160 - HEX 0xA0).

По какой-то причине (я не знаю, почему) французский язык ожидает, что символ пробела между цифрами будет нераскрывающимся пространством! Вы можете побаловать себя с помощью этой строки кода:

String num = "1 201"; 
num = num.replaceAll(" ", "\u00A0"); // '\u00A0' is the non breaking whitespace character! 

Таким образом, ваш код будет работать так, как ожидалось. Обратите внимание: если вы отформатируете double в String с французским языком, получившийся символ пробела будет NBSP тоже !!!

DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRENCH); 
System.out.println(df.format(1201.1)); 
// This will print "1 202,1" But the space character will be '\u00A0'! 
+0

Отличное наблюдение !!! +1 от меня. Для понимания этой ситуации нужна острая отладка. –

+0

Ну, это вполне логично, так как вы не хотите, чтобы ваш номер разбивался на две строки только потому, что в нем есть пробел!(число без пробелов не будет нарушено, если оно не будет занято самой полной линией) –

+0

Спасибо, паркер. Еще одно сомнение на ваше объяснение. Пожалуйста, дайте мне знать, если ниже код поможет разобрать без замены входных \t \t \t полукокса groupingSep = (decimalFormat.getDecimalFormatSymbols()) getGroupingSeparator(). \t \t \t, если (groupingSep == '\ u00A0') { \t \t \t \t groupingSep = ' «; \t \t \t \t DecimalFormatSymbols newSymbols = decimalFormat.getDecimalFormatSymbols(); \t \t \t \t новыйSymbols.setGroupingSeparator (groupingSep); \t \t \t \t decimalFormat.setDecimalFormatSymbols (newSymbols); \t \t \t} –

2

Вы можете использовать

String num = "1 201"; 
DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRANCE); 
System.out.println("Number Before parse: "+num); 

DecimalFormatSymbols symbols = df.getDecimalFormatSymbols(); 
symbols.setGroupingSeparator(' '); 
df.setDecimalFormatSymbols(symbols); 

double dm = df.parse(num).doubleValue(); 
System.out.println("Number After parse: "+dm); 

Ожидаемый выход:

Number Before parse: 1 201 
Number After parse: 1201.0 
+0

String num = "1 201"; Этот вход может быть в любом формате локали, таком как (1 201: 1,201 и т. Д.) Так что это решение невозможно в моем случае. По какой причине эта проблема? –

3

На самом деле, Java использует символ нерушимого пространство (\u00a0) для анализа французских чисел.

Таким образом, следующий код на самом деле работает:

String num = "1\u00a0201"; 
double dm = df.parse(num).doubleValue(); 
System.out.println("Number After parse: " + dm); 

См @ParkerHalo ответ, который предоставить более подробную информацию.

+0

его интересное наблюдение, почему бы кто-то его понизить? может быть, комментарий, как сделать его лучше? – nafas

+0

mate, чтобы ваше решение было ответом на вопрос, просто обратите внимание, что '' "следует заменить на" \ u00a0 "' – nafas

1

Это похоже на работу.

public double parse(String decimalAsText) { 
    NumberFormat decimalFormat = NumberFormat.getNumberInstance(Locale.FRANCE); 
    decimalAsText = decimalAsText.replace(' ', '\u00a0'); 
    ParsePosition pp = new ParsePosition(0); 
    Number n = decimalFormat.parse(decimalAsText, pp); 
    return n.doubleValue(); 
} 
Смежные вопросы