Ich habe ein Programm in C++ geschrieben, um alle Lösungen von a b \= c , donde a , b y c zusammen alle Ziffern 0-9 genau einmal verwenden. Das Programm durchlief eine Schleife über Werte von a y b und führte jedes Mal eine Ziffernzählroutine auf a , b y a b um zu prüfen, ob die Ziffernbedingung erfüllt wurde.
Allerdings können falsche Lösungen erzeugt werden, wenn a b die Ganzzahlgrenze überschreitet. Ich endete Überprüfung für diese mit Code wie:
unsigned long b, c, c_test;
...
c_test=c*b; // Possible overflow
if (c_test/b != c) {/* There has been an overflow*/}
else c=c_test; // No overflow
Gibt es eine bessere Möglichkeit, auf Überlauf zu testen? Ich weiß, dass einige Chips ein internes Flag haben, das gesetzt wird, wenn ein Überlauf auftritt, aber ich habe noch nie gesehen, dass man über C oder C++ darauf zugreifen kann.
Beachten Sie, dass unterzeichnet int
Überlauf ist undefiniertes Verhalten in C und C++ Man muss sie also aufspüren, ohne sie zu verursachen. Für den Überlauf von vorzeichenbehafteten Ints vor der Addition, siehe Erkennung von vorzeichenbehafteten Überläufen in C/C++ .
31 Stimmen
Informationen, die zu diesem Thema nützlich sein können: Kapitel 5 von "Secure Coding in C and C++" von Seacord - http://www.informit.com/content/images/0321335724/samplechapter/seacord_ch05.pdf SafeInt-Klassen für C++ - http://blogs.msdn.com/david_leblanc/archive/2008/09/30/safeint-3-on-codeplex.aspx - http://www.codeplex.com/SafeInt IntSafe-Bibliothek für C: - [ blogs.msdn.com/michael_howard/archiv
3 Stimmen
Seacord's Secure Coding ist eine großartige Ressource, aber verwenden Sie nicht IntegerLib. Siehe blog.regehr.org/archives/593 .
45 Stimmen
Die gcc-Compileroption
-ftrapv
führt dazu, dass er bei einem (vorzeichenbehafteten) Integer-Überlauf einen SIGABRT erzeugt. Siehe aquí .3 Stimmen
Das beantwortet zwar nicht die Frage des Überlaufs, aber eine andere Möglichkeit, das Problem anzugehen, wäre die Verwendung einer BigNum-Bibliothek wie GMP um zu gewährleisten, dass Sie immer über genügend Präzision verfügen. Sie müssen sich keine Sorgen über einen Überlauf machen, wenn Sie im Voraus genügend Ziffern zuweisen.
1 Stimmen
Die von @HeadGeek in seiner Antwort gegebenen Informationen entsprechen ziemlich genau dem, was ich auch sagen würde. Allerdings mit einem Zusatz. Die Art und Weise, wie Sie die Überfliegung bei einer Multiplikation jetzt erkennen, ist wahrscheinlich die schnellste. Auf ARM, wie ich in HeadGeeks Antwort kommentiert habe, können Sie die
clz
Anweisung oder die__clz(unsigned)
Funktion, um den Rang der Zahl zu bestimmen (wo ihr höchstes Bit ist). Da ich nicht weiß, ob diese Funktion auf x86 oder x64 verfügbar ist, gehe ich davon aus, dass sie es nicht ist, und sage, dass die Ermittlung des höchstwertigen Bits im schlimmsten Falllog(sizeof(int)*8)
Anweisungen.0 Stimmen
Eine Möglichkeit zur statischen Erkennung von Integer-Überläufen (mit False Positives): usenix.org/conference/osdi12/technical-sessions/presentation/