2016-08-11 3 views
2

Ich muss einen doppelten Wert (Zentimeter) in einen Bruchwert mit diesem Format konvertieren: 3 1/64 (Zoll). Nachdem ich viel darüber gelesen habe und Algorithmen für die Umwandlung in Brüche gefunden habe, denke ich, dass sie für das, was ich brauche, nicht gut sind, weil meine Brüche in diesen Formaten sein sollten:?/2,?/4,?/8,?/16, ?/32,?/64. Ich habe Konvertierungstabellen wie folgt gesehen: table. Und ich denke, meine beste Lösung ist, einen Schlüssel, eine Werteliste mit allen Werten in der Tabelle zu erstellen und für jede Zahl die beste Annäherung in der Liste zu finden.In Bruchzahl umrechnen

Zum Beispiel: 3,21 cm. = 1,26378 in = 1 in + 0,26378. Also, nach der Tabelle verknüpft, 0,26378 = 17/64. Und das Endergebnis sollte 1 17/64 Zoll sein.

Also meine Fragen sind:

  1. Ist eine gute Idee, eine Liste mit den Werten in der Tabelle zu haben und den nächsten Wert finden, um den Anteil zu geben, oder ist es besser, einen Algorithmus zu schaffen Dies?

  2. Wenn es in Ordnung ist, eine Liste mit den Werten zu erstellen, wie kann ich den nächsten Wert einer gegebenen Nummer in meiner Liste finden?

+0

Problem mit einem Tisch ist, was passiert, wenn Sie einen Wert größer als jede der Tabelle dargestellt werden? Es ist nichts falsch daran, einen Algorithmus zu verwenden - Sie erhalten eine genauere Antwort. Wenn Sie es dem Benutzer in einem bestimmten Format zeigen müssen, gibt es eine mathematische Methode, um herauszufinden, wie das aussehen soll. – ADyson

+0

Nein. Ihr Problem kann einfach in Binärform definiert werden. Dann wandle einfach die binäre Expansion durch Linksverschiebung in einen Bruch um. – Aron

Antwort

3

Ich schlage vor, mit einfacher Mathematik statt Tabelle

private static string ToFraction64(double value) { 
    // denominator is fixed 
    int denominator = 64; 
    // integer part, can be signed: 1, 0, -3,... 
    int integer = (int) value; 
    // numerator: always unsigned (the sign belongs to the integer part) 
    // + 0.5 - rounding, nearest one: 37.9/64 -> 38/64; 38.01/64 -> 38/64 
    int numerator = (int) ((Math.Abs(value) - Math.Abs(integer)) * denominator + 0.5); 

    // some fractions, e.g. 24/64 can be simplified: 
    // both numerator and denominator can be divided by the same number 
    // since 64 = 2 ** 6 we can try 2 powers only 
    // 24/64 -> 12/32 -> 6/16 -> 3/8 
    // In general case (arbitrary denominator) use gcd (Greatest Common Divisor): 
    // double factor = gcd(denominator, numerator); 
    // denominator /= factor; 
    // numerator /= factor; 
    while ((numerator % 2 == 0) && (denominator % 2 == 0)) { 
    numerator /= 2; 
    denominator /= 2; 
    } 

    // The longest part is formatting out 

    // if we have an actual, not degenerated fraction (not, say, 4 0/1) 
    if (denominator > 1) 
    if (integer != 0) // all three: integer + numerator + denominator 
     return string.Format("{0} {1}/{2}", integer, numerator, denominator); 
    else if (value < 0) // negative numerator/denominator, e.g. -1/4 
     return string.Format("-{0}/{1}", numerator, denominator); 
    else // positive numerator/denominator, e.g. 3/8 
     return string.Format("{0}/{1}", numerator, denominator); 
    else 
    return integer.ToString(); // just an integer value, e.g. 0, -3, 12... 
} 

Tests

const double cmInInch = 2.54; 

// 1 17/64 
Console.Write(ToFraction64(3.21/cmInInch)); 
// -1 17/64 
Console.Write(ToFraction64(-1.26378)); 
// 3 1/4 
Console.Write(ToFraction64(3.25001)); 
// 3 1/4 
Console.Write(ToFraction64(3.24997)); 
// 5 
Console.Write(ToFraction64(5.000001)); 
// -1/8 
Console.Write(ToFraction64(-0.129)); 
// 1/8 
Console.Write(ToFraction64(0.129)); 
+0

Die Frage fehlt Erklärung des Algorithmus. Iterieren Sie Nenner von "64" bis zum Ende (32, 16, ... 2) und prüfen Sie den Fehler, um die beste Übereinstimmung zu finden oder was? Oder funktioniert es nur für * exakte * Werte? – Sinatr

+0

@ Sinatr: Ich berechne den nächsten Nominator, z.B. '24' und dann versuchen * das * Verhältnis' 24/64' zu vereinfachen *, indem wir sowohl 'Zähler' als auch' Nenner' durch denselben Wert teilen (da '64 == 2 ** 6' können wir Potenzen von zwei ausprobieren): '24/64 == 12/32 == 6/16 == 3/8' –

+0

Ich sehe jetzt, danke für die Erklärung. Also extrahierst du grundsätzlich den Bruchteil, multiplizierst ihn mit Nenner, runder und vereinfachst dann: 37.4 = 37 + 0.4, dann 0.4 = (0.4 * 64 + 0.5)/64 = 26.1/64 ~ 26/64 = 13/32. – Sinatr

Verwandte Themen