2012-12-16 14 views
15

Simile a this question solo in C# invece di JavaScript. Non ho trovato nulla per C# durante la ricercaConvertire una frazione di testo in un decimale

Ho una casella di testo che prenderà una quantità, che verrà successivamente memorizzata come una doppia in un database. Tuttavia è possibile che alcune quantità vengano immesse come frazioni di stringa, ad esempio 1/2 per 0,5. Voglio essere in grado di convertirli in decimali prima di memorizzarli nel database (essere in grado di riconvertire anche sarebbe bello ma non necessario). Voglio essere in grado di gestire entrambe le frazioni e i numeri misti, ad es. 2 1/2 è salvato come 2.5

Qualcuno conosce un modo per farlo?

+0

Scoprirei in una libreria di analisi che cerca elementi comuni come spazi, '/' e così via con 'Int32.Parse' e ​​restituisce il risultato. –

+0

http://www.codeproject.com/Articles/9078/Fraction-class-in-C –

risposta

11

prova a dividerla sullo spazio and slash, qualcosa come:

double FractionToDouble(string fraction) { 
    double result; 

    if(double.TryParse(fraction, out result)) { 
     return result; 
    } 

    string[] split = fraction.Split(new char[] { ' ', '/' }); 

    if(split.Length == 2 || split.Length == 3) { 
     int a, b; 

     if(int.TryParse(split[0], out a) && int.TryParse(split[1], out b)) { 
      if(split.Length == 2) { 
       return (double)a/b; 
      } 

      int c; 

      if(int.TryParse(split[2], out c)) { 
       return a + (double)b/c; 
      } 
     } 
    } 

    throw new FormatException("Not a valid fraction."); 
} 

Hey, it worked! Ricordarsi di verificare la presenza di una divisione per zero, anche. Come risultato, otterrai Infinity, -Infinity o NaN.

+1

Grazie mille! Ho appena implementato questo nella mia app e funziona perfettamente. –

+0

Perché è necessario utilizzare un delimitatore '' (lo spazio)? @ U2744 SNOWFLAKE –

+0

Inoltre, non funziona semplicemente la seguente linea? emette correttamente. double frac = (doppio) 1/8; –

1

Dividere la stringa sul "/" quindi dividere i due numeri.

public float FractionToDecimal(String input) 
{ 
    String[] fraction = input.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); 
    if (fraction.Length != 2) 
    { 
     throw new ArgumentOutOfRangeException(); 
    } 
    Int32 numerator, denominator; 
    if (Int32.TryParse(fraction[0], out numerator) && Int32.TryParse(fraction[1], out denominator)) 
    { 
     if (denominator == 0) 
     { 
      throw new InvalidOperationException("Divide by 0 occurred"); 
     } 
     return (float)numerator/denominator; 
    } 
    throw new ArgumentException(); 
} 
7

E qui è ancora una soluzione in più, ma con un po 'più seamless an integration:

public class FractionalNumber 
{ 
    public Double Result 
    { 
     get { return this.result; } 
     private set { this.result = value; } 
    } 
    private Double result; 

    public FractionalNumber(String input) 
    { 
     this.Result = this.Parse(input); 
    } 

    private Double Parse(String input) 
    { 
     input = (input ?? String.Empty).Trim(); 
     if (String.IsNullOrEmpty(input)) 
     { 
      throw new ArgumentNullException("input"); 
     } 

     // standard decimal number (e.g. 1.125) 
     if (input.IndexOf('.') != -1 || (input.IndexOf(' ') == -1 && input.IndexOf('/') == -1 && input.IndexOf('\\') == -1)) 
     { 
      Double result; 
      if (Double.TryParse(input, out result)) 
      { 
       return result; 
      } 
     } 

     String[] parts = input.Split(new[] { ' ', '/', '\\' }, StringSplitOptions.RemoveEmptyEntries); 

     // stand-off fractional (e.g. 7/8) 
     if (input.IndexOf(' ') == -1 && parts.Length == 2) 
     { 
      Double num, den; 
      if (Double.TryParse(parts[0], out num) && Double.TryParse(parts[1], out den)) 
      { 
       return num/den; 
      } 
     } 

     // Number and fraction (e.g. 2 1/2) 
     if (parts.Length == 3) 
     { 
      Double whole, num, den; 
      if (Double.TryParse(parts[0], out whole) && Double.TryParse(parts[1], out num) && Double.TryParse(parts[2], out den)) 
      { 
       return whole + (num/den); 
      } 
     } 

     // Bogus/unable to parse 
     return Double.NaN; 
    } 

    public override string ToString() 
    { 
     return this.Result.ToString(); 
    } 

    public static implicit operator Double(FractionalNumber number) 
    { 
     return number.Result; 
    } 
} 

E perché implementa l'operatore implicita, può essere utilizzato semplicemente:

Double number = new FractionalNumber("3 1/2"); 

Tutto ciò che non può essere analizzato restituisce la costante doppia Double.NaN. Senza entrare in una lista di possibili input, questo ha funzionato con alcune nozioni di base. Sentiti libero di modificare la classe in base alle tue esigenze.

-2
decimal re = (decimal)1/7; 

funziona per me.

+0

Il compilatore può fare questo perché quelli sono letterali numerici e '/' forma un'espressione matematica. '(decimale)" 1/7 "' fallirà miseramente. – BradleyDotNET

+0

È vero. Ho semplicemente ignorato il "testo" nella parte del testo, mi scuso. Esegui la funzione "fractiontodouble" da un altro utente, prima, ma modificalo in modo che sia fractiontodecimal. –

Problemi correlati