2016-12-12 4 views
0

in letzter Zeit habe ich versucht, meine auf Big Integer-Klasse zu machen. Im Moment habe ich einige Prototypen gemacht, die fast funktionieren. Dieser Prototyp ist weder eine Funktion, noch eine Klasse, nur ein schneller Zeuge, um zu sehen, ob es funktioniert.BigInteger Implementierung, tragen Diskrepanz

Das ist mein Prototyp bisher: (es mit allen Abgüsse ein bisschen hässlich sieht nur den Compiler zu gefallen)

std::vector<long long unsigned> vec1 {4294967295, 2294967295, 1294967295}; 
    std::vector<long long unsigned> vec2 {4294967295, 2294967295, 1294967295}; 

    int carry {}; 
    for (int i {static_cast<int>(vec1.size()) - 1}; i != -1; --i) { 
     int unsigned greater = static_cast<unsigned int>(std::max(vec1[i], vec2[i])); 
     int unsigned result {}; 

     if (i < static_cast<int>(vec2.size())) { 
      result = static_cast<int unsigned>(vec2[i] + vec1[i] + carry); 
     } else if (carry) { 
      result = static_cast<int unsigned>(vec1[i] + carry); 
     } else { 
      break; 
     } 

     if (result <= greater) { 
      vec1[i] += result; 
      carry = 1; 
     } else { 
      vec1[i] = result; 
      carry = 0; 
     } 
    } 

    if (carry) { 
     vec1.back() += 1; 
    } 

    for (auto const n : vec1) { 
     cout << n; 
    } 

Und das ist das Ergebnis:

858993459025899345892589934591 
       ^  ^
858993459045899345902589934590 -> the correct one! 

Also, was Ich mache falsch?

Es gibt das gleiche Ergebnis in GCC und Visual Studio.

+0

Neugierig, warum "int unsigned größer" verwenden, während vec1 und vec2 "lang lang unsigned" sind? –

+0

Dies ist kein [MCVE] (https://stackoverflow.com/help/MCVE), da unklar ist, wie Sie diesen Code aufrufen oder die Ergebnisse anzeigen. Bitte geben Sie genügend Code an, um Ihre korrekten und falschen Ergebnisse zu reproduzieren. Es ist nicht völlig nutzlos, aber ich dachte, ich würde das erwähnen, während ich mir ansehe, was du hast, falls das Problem nicht da ist. – ShadowRanger

+0

Ich dachte nicht einmal über diese xD, die nur ein Prototyp war ich zu sehen, wie Sachen funktioniert, es ist normal, wenn es eilte –

Antwort

0

Dies

if (carry) { 
    vec1.back() += 1; 
} 

fügt man zum letzten ist.

Vielleicht möchten Sie einen nach vorne einfügen?

1

Wie geschrieben, wenn der höchste Betrag hinaus trägt, am Ende Sie den niedrigsten Betrag Wert erhöhen:

if (carry) { 
    vec1.back() += 1; 
} 

Vermutlich wäre das richtige Verhalten der neuen zu besetzen höchsten, den Vektor und erlauben den Übertrag zu erweitern Wert, zB:

if (carry) { 
    vec1.insert(vec1.begin(), 1); 
} 

das bedeutet Sie vec1 am Ende erweitert (und alle vorhandenen Werte zu kopieren, weil Einfügen am Anfang eines vector ist nicht billig), die möglicherweise oder möglicherweise nicht korrekt sein Angesichts des Designs Ihrer Klasse (Ihre Additionsoperation sieht unsicher aus, wenn vec1 und vec2 keine übereinstimmende Größe haben, daher ist unklar, ob vec1 erweitert werden darf).

+1

Ich bevorzuge es, den Vektor Little Endian anzuordnen, so dass das Hinzufügen einer neuen höchsten Ziffer ein 'push_back' anstelle von' insert' ist. Siehe http://stackoverflow.com/a/22004815/5987 @ –

+0

@MarkRansom: Einverstanden, alle Multipräzisions-Integer-Bibliotheken, die ich kenne, speichern die Magnitude mit den "Wörtern" in Little-Endian-Reihenfolge, weil es viel einfacher ist, wenn Sie es brauchen aufgrund des Tragens erweitern.Es bedeutet auch, dass Sie Speicher in sequentieller Reihenfolge lesen/schreiben, was bei einigen Architekturen hilfreich sein kann, und selbst wenn dies nicht der Fall ist, ist es normalerweise einfacher zu programmieren. – ShadowRanger

+0

Wenn Sie bemerken, die Vorderseite ist gut geformt, das Problem entsteht in der Rückseite des Vektors: Ich bearbeitet, um deutlich zu zeigen, wo die Diskrepanz passiert. Beachten Sie auch, dass meine for-Schleife umgekehrt ist. –