Frage

Ich habe diesen Code

#include <iostream>

using namespace std;

int main(int argc,char **argv) {

    unsigned long long num1 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995LL;
    unsigned long long num2 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996LL;
    unsigned long long num3 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997LL;
    unsigned long long num4 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998LL;
    unsigned long long num5 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999LL;

    cout << (unsigned long long)(num1 * num2 * num3 * num4 * num5) << endl;
    return 0;
}

Wie Sie die Zahlen sehen können, sind enorm, aber wenn ich die Mathematik zu tun dort bekomme ich diese: 18446744073709551496

Beim Kompilieren erhalte ich diese Warnungen:

warning: integer constant is too large for its type|
In function `int main(int, char**)':|
warning: this decimal constant is unsigned only in ISO C90|
...
War es hilfreich?

Lösung

Ihr Ergebnis ist größer als die lange, lange Art - Sie in einem BigInteger oder beliebige Genauigkeit Bibliothek , so etwas wie gmp

Andere Tipps

Diese Zahlen werden nicht in jede C ++ Datentypen passen. Wenn Sie sie einfach ausdrucken möchten, speichern Sie die Nummern in einer Zeichenkette. Wenn Sie es tun Mathe wollen, mit beliebiger Genauigkeit Mathematik-Bibliothek finden und verwenden.

Wenn Sie Literale wollen diese groß in Ihrem Code Sie eingeben müssen, um sie als Zeichenkette und sie in eine BigInt Klasse von einer Art laden. Es gibt keine Möglichkeit, jetzt Ganzzahlliterale so groß im Quellcode zum Ausdruck bringen (obwohl C ++ 0x hoffentlich, dass Fehlbetrag-Adresse).

Wenn Sie mit der BigInteger Bibliothek, werfen Sie einen Blick auf die stringToBigUnsigned Funktion in BigIntegerUtils.hh für Gebäude eine große Zahl von einer Zeichenkette.

#include "BigUnsigned.hh"
#include "BigIntegerUtils.hh"     

 BigUnsigned  num1 = stringToBigUnsigned (
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999995"
    );

Was ist es, Sie versuchen zu tun? Verstehen Sie die Grundlagen der Binär- und Dezimalzahlen? Warum 8 Bits hält nur die Werte 0 bis 255, 12 Bit 0-4095, etc? Wie viele Bits dauert es, die Zahl, die Sie interessiert sind zu halten? Oder besser, wie groß der Zahl sind Sie interessiert zu schaffen? Und verwenden Sie 9s die Nummer größer zu machen? Was ist hex 0 × F ... statt? Wenn Sie die größte Zahl ohne Vorzeichen wollen (innerhalb einer der Standard-Integer-Typen), warum nicht:

unsigned long long a, b;

a = -1; // das scheint nur falsch Vermischung mit und ohne Vorzeichen, aber es gilt, wird die Zahl in unsigned konvertiert vor dem Speichern

b = 0; b--; // macht das Gleiche wie oben

Sie müssen Präzision auf dieser Ebene Sie wirklich? Sie erkennen, dass vervielfacht doppelt so groß wie jeder Operanden ein Ergebnis erfordern kann? 0xFF * 0xFF = 0xFE01, wenn Sie in diesem Fall 8 Bit-Integer wurden verwendet, könnte man die Mathematik nicht. Es wird nur noch schlimmer, wie Sie weiter 0xFF * 0xFF * 0xFF = 0xFD02FF multiplizieren.

Was zu tun versuchen?


Sehen Sie Ihre Antwort:

Ich habe nicht Eulersche Zahl 8 gesehen. Klingt wie ein gutes Interview Frage, da es nur ein paar Zeilen Code nimmt zu lösen.


Ihre andere Antwort:

Zahlen ...

Wahrscheinlich, weil wir 10 Finger haben (und vielleicht 10 Zehen) wir mit „Basis 10“ aufzuwachsen. Unsere Uhren sind Basis 60 zum größten Teil aber mit Base wurde 10 gemischt, um es noch verwirrender zu machen. Wie auch immer, Basis 10, bedeutet für jede Zahl Platzhalter Sie eines von 10 einzigartigen Ziffern haben, wenn Sie das Maximum an diesem Ort zum nächsten Ort rollen erreichen. Das ist alles, Grundschule Sachen.

000
001
002
003
...
008
009
010
011
012
...

Sehen Sie, wie die am weitesten rechts stehende Ziffer 10 Symbole hat (0,1,2,3,4,5,6,7,8,9), und wenn es das letzte Symbol erreicht es beginnt immer und derjenige auf der linken Seite es wird um eins erhöht. Diese Regel ist für alle Basisnummerierungssysteme wahr.

Es ist wahr, für die Basis 2, außer es gibt nur zwei Symbole, 0 und 1

000
001
010
011
100
101
...

Das gleiche gilt für Oktal, aber 8 Symbole (0,1,2,3,4,5,6,7)

000
001
002
003
004
005
006
007
010
011
012
013
...

Und das gleiche gilt für hexadezimal, 16 Symbole (0,1,2,3,4,5,6,7,8,9, a, b, c, d, e, f)

000
001
002
003
004
005
006
007
008
009
00a
00b
00c
00d
00e
00f
010
011
012
013
...

Ich wollte in die whys gehen binäre über andere Basen der Verwendung (wie 10) in Computern. Unterm Strich ist es einfach, zwei Zustände zu haben, ein- oder auszuschalten, oder hoch und niedrig. Zwei Staaten sind wie zwei Symbole 1 und 0 in der Basis 2. Den Versuch, Elektronik zu halten abgestimmt, um mehr als zwei Zustände innerhalb der zur Verfügung stehenden Spannung ist hart, es zumindest früher, es in der Nähe von null Volt oder über einige kleine Anzahl von Volt zu halten ist relativ einfach, so digitale Elektronik verwendet zwei Zustände, binär.

Auch eine einfache Aufgabe für einen Menschen in binär ist langatmig, einfache zweite Klasse in Mathe ist immer noch eine Menge von Einsen und Nullen. So Oktal wurde populär, weil es Ihnen in Gruppen von drei Bits zu denken erlaubt und man konnte Symbole verwenden wir vertraut sind als Zahlen 0,1,2,3,4,5,6,7. Aber Gruppen von vier, die eine andere Potenz von 2 ist, gibt den Menschen viel mehr geistige Rechenleistung als Oktal wird hex auf 4 Bits basiert, die auch eine Potenz von 2 Wir mussten mehr Symbole auf den 10 fügen wir von der geliehene traditial arabicum Basis 10, so dass die ersten 6 des Alphabets verwendet wurde. Octal ist selten, wenn überhaupt verwendet wird, kann man jemandes Alter sagen, ob sie statt hex Oktal denken. (Ich bin von der Hex-Generation, sondern habe mit denen aus der Oktal-Generation gearbeitet, die mit hex kämpfen, weil sie nicht von Oktal-Binär bekommen können in ihrem Kopf hex).

Basis 10 in einem Computer ist wiedie durchschnittlichen menschlichen Denken in hex. Computer dont do Basis 10 (gut für faule Menschen sie verwendet bcd zu tun), sie tun Basis 2. Die Dezimalzahl 1234 in einem Computer ist wirklich 0x4D2 oder 0b010011010010. Das ist als ein Wert, sagen Sie 1234 plus einige andere Nummer hinzufügen möchten, müssen Sie diesen Wert, die nichts mit den SymbOS zu tun hat 1, 2, 3 und 4. Aber diese Antwort schreiben auf Stackoverflow wir die Zahl nicht verwenden wir verwenden ASCII, so 1234 in ascii 0x31, 0x32, 0x33, 0x34, die für Ihre euler Lösung unter der Annahme der 1000-stellige Nummer ist wichtig zu wissen, wurde als ASCII-String zur Verfügung gestellt, die es haben würde, oder Sie würde es konvertieren von binär in aSCII, da das Problem eine Basis 10 Problem und nicht die Basis 2 durch Definition ist.

Also zurück zu dem, was ich hatte gefragt. Angenommen, Sie hatten 4 Speicherbits eine Nummer zu speichern, wie groß der Zahl könnte Sie speichern? Wenn Sie denken Basis 10 nur könnte man denken, diese Zahl ein 9 ist, da Sie trainiert sind für die Verwendung der größte Symbol in jeder Speicherstelle zu denken, 99999 ist die größte Zahl, wenn Sie fünf Speicherplätze in der Basis haben 10. Zurück zu vier Bits aber das größte Symbol für ein einzelnes Bit 1 ist, setzen Sie diese Zahl in jeder Speicherstelle erhalten Sie 1111 (vier Einsen). Allein aus diesen vier diejenigen suchen, sollten Sie in der Lage sein, im Kopf die Oktal und hex Version derselben Nummer 17 Oktal oder F hex leicht zu sehen. Um dezimal zu sehen nimmt Mathe, oder in diesem Fall des Auswendiglernen, diese Zahl ist 15 dezimal. So ist die größte Vier-Bit-Zahl, die Sie haben können, ist 0xF oder 15 nicht 9. Was ist mit einer 8-Bit-Zahl? 0xFF oder 255 (2 bis 8. Leistungs minus eins). Größte 16-Bit-Zahl? 65535, etc.

Also, wenn ich fragen, wie viele Bits versuchen Sie, diese zu verwenden, was ich meine. Schauen Sie sich diese Nummer 99999. Wieder 10 stützen würden Sie denken, dass die größte Zahl ist, sondern an einen Computer ist es nur dort teilweise, 99999 dezimal ist 0x1869F, die 17 Bit-Speicher zum Speichern nimmt, die größte 17-Bit-Nummer, die Sie kann Laden ist 0x1FFFF die 131.071 ist, die etwas größer als 99999 ist also, wenn Sie große Zahlen und Mathematik auf einem Computer, den Sie haben zu denken binär (oder hex).

denken

Ursprünglich hast du Multiplikationen, die immer noch Teil des euler Problem, aber was sollte ich fragte nach wurde auf Präzision und wenig Speicherung. Hier sind einige Grundlagen, und ich werde nicht in sie erhalten, aber Sie können sehen, warum wir auf Floating-Point-Einheiten in Computern verlassen.

Nehmen Sie die größte 4-Bit-Zahl 1111 (binär), die 15 dezimal ist. Hinzufügen, dass mit der größten Vier-Bit-Zahl und Sie erhalten 15 + 15 = 30 = 0x1E oder 11110 binär. So hinzuzufügen zwei Vier-Bit-Zahlen, die Sie benötigen fünf Bits Ihre Antwort zu halten. Computer halten ein „tragen“ Bit für dieses Extra. Im Wesentlichen lassen sich die Addition / Subtraktion integer mathematische Funktionen in dem Computer, den Sie N + 1 Bits haben. Also, wenn es sich um ein 32-Bit-Computer, die Sie haben im Grunde 33 Bits für add / sub math.

Das Problem ist, multiplizieren und dividieren, die heute noch viele Prozessoren nicht unterstützen (ja viele haben keine FPU und nur addieren und subtrahieren, manchmal mehrfach, aber divide ist selten. Multiplizieren und Dividieren viel Elektronik der Trade-off nehmen mit fügt ist, dass Sie sie tun können, und subtrahiert in Software). Nehmen Sie den schlimmsten Fall mehrfach für ein Vier-Bit-System 1111 * 1111 = 11.100.001 so dauert es 8 Bits das Ergebnis eines 4 Bit speichern multiplizieren, werden Sie schnell feststellen, dass, wenn Sie hatten ein 4-Bit-System Die meisten der vervielfacht Sie eine Nummer führt zu tun möchten, die gespeichert werden können, nicht in 4 Bits. Also, wenn ich sehe, Sie 64-Bit-Integer nehmen (die unsigned long long ist oft 64 Bit) und viermal multipliziert wird, das heißt, müssen Sie 64 * 5 oder ein 320-Bit-Integer Ihre Antwort zu speichern, haben Sie versucht, diese Antwort in einem setzen 64 großes Ergebnis, das sehr oft, auf dem Compiler und Computer abhängig wird gerne tun und die oberen Bits so dass Sie mit den unteren 64 Bits des Ergebnisses gestutzt, die leicht kleiner als Ihre Operanden suchen, die ist, was ich gedacht hatte, Sieauf dem ersten getan hat.

Gleitpunkt ist nicht viel mehr als die wissenschaftliche Schreibweise aber in binär, wenn Sie die Nummer 1234 und 5678 wissenschaftlicher Notation multiplizieren wollte man 1.234 * 10 ^ 3 mal 5,678 * 10 ^ 3 nehmen und erhalten 7,007 * 10 ^ 6 . Sie behalten Ihre Präzision und sind in der Lage eine breitere Palette von Zahlen darzustellen. Ich werde nicht erhalten in, wie das funktioniert in binär. Aber es funktioniert nicht für Ihre ursprüngliche Frage arbeiten.

Ahh, das letzte, was zu klären, was ich in meiner Frage / Antwort zu tun. Negative Zahlen in binär. Aufgrund der Beziehungen zwischen Addition und Subtraktion und Basissystemen können Sie ein paar Tricks spielen. Sage ich subtrahieren 1 von der Zahl 7 (dezimal) mit binären wollte. Nun, es ist nicht so etwas wie eine Subtraktionsschaltung, Sie stattdessen eine negative Zahl hinzufügen, so dass anstelle von 7 - 1 ist wirklich 7 + (-1), es macht einen Unterschied:

0111 + ???? = 0110

Welche Zahl könnte man bis 7 hinzufügen 6 zu bekommen ... in binären?

0111 + 1111 = 0110

Negative Zahlen in binär sind „Zweier-Komplement“ genannt, lange Geschichte kurz die Antwort „Invert und fügen 1“ ist. Wie stellen Sie minus 1 in binärer? nehmen plus eine 0001 dann invertieren die, die Nullen und die Nullen diejenigen machen Sinn (auch als Einerkomplement bekannt) 1110 fügen Sie dann eine 1111. Minus ist eine spezielle Nummer in Computern (auch überall) als egal, wie viele Bits haben Sie es ist als alle diejenigen vertreten. Also, wenn Sie sehen, dass jemand dies tun:

unsigned char a;

a = -1;

Der Compiler zuerst an das sieht -1 und denkt ... 11111 (binär), dann sieht es auf das Gleichheitszeichen und die andere Seite, oh, wollen Sie alle diejenigen sein, sieht es, dass Sie eine ganze Zahl mit Vorzeichen haben und eine nicht unterzeichnete, aber die Umwandlung ist nur die Bits bewegen über, so dass Sie sagen, über dass Sie a = 0xFF; (Ein 8-Bit unsigned char vorausgesetzt).

Einige Compiler kann sich beschweren, dass Sie eine negative Zahl in einer Zahl ohne Vorzeichen zu speichern versuchen. Andere Compiler werden die betrachten -1 und sehen es als ein 32-Bit oder in diesen Tagen vielleicht 64-Bit-Integer-Konstante unterzeichnet und dann, wenn es wertet die Gleichen in einen 8-Bit unsigned Sie eine Warnung erhalten, dass man nicht speichern -1 in einem signierten oder unsigned char ohne Typumwandlung. Aber wenn Sie dies tun:

a = 0; a -;

Alle Compiler so. und werden nicht beschweren, es brennt nur Rechenzyklen zur Laufzeit statt der Kompilierung.

Jetzt irgendwo ein Freund erzählte mir von einem Buch, das seriell binäre Mathematik tut. Zum Beispiel eine Zahl zu negieren, in der Regel Sie die Invert und Anzeige einen Trick tun, sondern mit Bleistift und Papier einige können Sie den anderen Trick erzählen. Ausgehend von der rechten Kopie der Nullen bis einschließlich die ersten 1 dann danach invertieren, so minus 2

0010
1110

von rechts Kopie starten 0, dann die erste, dann invertieren die verbleibenden Bits, wie Sie links.

minus 6

0110
1010

minus 4

0100
1100

Angeblich gibt es Tricks addieren und subtrahieren (gut duh, das ist einfach), sondern auch multiplizieren und dividieren. Wenn Sie sie seriell dann können Sie tun, unendlich lange Mathe binär mit dem gleichen Alu. Wenn Sie wissen sind, wie zu tun, dass Sie, dass in der Software und Ihre ursprüngliche Frage zu multiplizieren großen Konstanten implementieren könnten (unter der Annahme, alle die Genauigkeit des Halts) ist auf jedem Computer trivial.

Die Antwort, die du hast, 18446744073709551496, ist darauf zurückzuführen, Ihre 999 ... 9s abgeschnitten wird, wenn auf eine lange, lange zugewiesen, und die mehrere Operationen überfüllt. Seine deterministisch, aber effektiv nur eine zufällige Ansammlung von Bits.

unsigned int stellt ein Systemwort. Heute, das Wort wird max out entweder 2 ^ 32 -1 oder 2 ^ 64-1, je nachdem, ob Ihr System 32-Bit oder 64-Bit. Sie schlagen die Kappe.

Sie haben eine bignum Klasse zu schreiben oder eine aus dem ‚Netz verwenden.

Warum tun Sie dieses Problem überhaupt?

Die Zahlen können nicht in unsigned long long Bereich passen also entweder Sie GMP-Bibliothek oder die Verwendung Zeichenfolge große Zahlen darzustellen verwenden könnte, wie ich für die Berechnung der Fakultät Zahl wie 50 tat:

http://codepad.org/bkWNV0JC

#include <cmath>
#include <iostream>
using namespace std;
int main()
{
  unsigned int nd, nz;   
  unsigned char *ca;   
  unsigned int j, n=50, q, temp;
  int i;
  double p;
    p = 0.0;
    for(j = 2; j <= n; j++)
    {
      p += log10((double)j);  
    }
    nd = (int)p + 1;

    ca = new unsigned char[nd+1];
    if (!ca)
    {
      cout << "Could not allocate memory!!!";
      exit(0);
    }
    for (i = 1; (unsigned)i < nd; i++)
    {
      ca[i] = 0;
    }
    ca[0] = 1;

    p = 0.0;
    for (j = 2; j <= n; j++)
    {
      p += log10((double)j);   
      nz = (int)p + 1;        
      q = 0;                  
      for (i = 0;(unsigned) i <= nz; i++)
      {
        temp = (ca[i] * j) + q;
        q = (temp / 10);
        ca[i] = (char)(temp % 10);
      }
    }

    cout << "\nThe Factorial of " << n << " is: ";
    for( i = nd - 1; i >= 0; i--)
    {
      cout << (int)ca[i];
    }
  //  delete []ca;    
  return 0;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top