Analizza un numero dalla notazione esponenziale

Ho bisogno di analizzare la stringa “1.2345E-02” (un numero express in notazione esponenziale) in un tipo di dati decimale, ma Decimal.Parse("1.2345E-02") genera semplicemente un errore

È un numero in virgola mobile, devi dirlo che:

 decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float); 

Funziona se si specifica NumberStyles.Float :

 decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float); Console.WriteLine(x); // Prints 0.012345 

Non sono del tutto sicuro del motivo per cui questo non è supportato per impostazione predefinita: il valore predefinito è utilizzare NumberStyles.Number , che utilizza gli stili AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint e AllowThousands. Forse è legato alle prestazioni; specificare un esponente è relativamente raro, suppongo.

Oltre a specificare NumberStyles, ti consigliamo di utilizzare la funzione decimal.TryParse come:

 decimal result; if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) ) { // do something in case it fails? } 

In alternativa a NumberStyles. Puoi utilizzare un set specifico se sei certo dei tuoi formati. per esempio:

 NumberStyles.AllowExponent | NumberStyles.Float 
  static void Main(string[] args) { decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float); } 

Sii cauto sulla risposta selezionata: c’è una sottigliezza che specifica System.Globalization.NumberStyles.Float in Decimal.Parse che potrebbe portare a System.FormatException perché il tuo sistema potrebbe essere in attesa di un numero formattato con ‘,’ invece di ‘.’

Ad esempio, in notazione francese, “1.2345E-02” non è valido, devi prima convertirlo in “1.2345E-02”.

In conclusione, usa qualcosa come:

 Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float); 

Ho riscontrato che il passaggio in NumberStyles.Float , in alcuni casi, modifica le regole in base alle quali viene elaborata la stringa e genera un output diverso da NumberStyles.Number (le regole predefinite utilizzate da decimal.Parse ).

Ad esempio, il codice seguente genererà un FormatException nella mia macchina:

 CultureInfo culture = new CultureInfo(""); culture.NumberFormat.NumberDecimalDigits = 2; culture.NumberFormat.NumberDecimalSeparator = "."; culture.NumberFormat.NumberGroupSeparator = ","; Decimal.Parse("1,234.5", NumberStyles.Float, culture); // FormatException thrown here 

Mi consiglia di utilizzare l’input NumberStyles.Number | NumberStyles.AllowExponent NumberStyles.Number | NumberStyles.AllowExponent , in quanto ciò consentirà numeri esponenziali e continuerà a elaborare la stringa secondo le regole decimal .

 CultureInfo culture = new CultureInfo(""); culture.NumberFormat.NumberDecimalDigits = 2; culture.NumberFormat.NumberDecimalSeparator = "."; culture.NumberFormat.NumberGroupSeparator = ","; Decimal.Parse("1,234.5",NumberStyles.Number | NumberStyles.AllowExponent, culture); // Does not generate a FormatException 

Per rispondere alla domanda del poster, la risposta corretta dovrebbe invece essere:

 decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent); Console.WriteLine(x); 

Avviso sull’uso di NumberStyles.Any:

“6.33E + 03” converte in 6330 come previsto. In tedesco, i punti decimali sono rappresentati da virgole, ma 6,33E + 03 convertiti in 633000! Questo è un problema per i miei clienti, poiché la cultura che genera i dati non è nota e potrebbe essere diversa dalla cultura che opera sui dati. Nel mio caso, ho sempre una notazione scientifica, quindi posso sempre sostituire la virgola al punto decimale prima di analizzare, ma se stai lavorando con numeri arbitrari, come numeri abbastanza formattati come 1.234.567, allora quell’approccio non funziona.