Ich möchte besser wissen, wann ich besetzen soll. Was sind die impliziten Typkonvertierungsregeln in C ++ beim Hinzufügen, Multiplizieren usw. Zum Beispiel:
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
und so weiter...
Wird der Ausdruck immer als der genauere Typ bewertet? Unterscheiden sich die Regeln für Java? Bitte korrigieren Sie mich, wenn ich diese Frage falsch formuliert habe.
^
ist XOR.Antworten:
In C ++ wirken Operatoren (für POD-Typen) immer auf Objekte desselben Typs.
Wenn sie also nicht gleich sind, wird einer befördert, um mit dem anderen übereinzustimmen.
Der Typ des Ergebnisses der Operation ist der gleiche wie bei Operanden (nach der Konvertierung).
Hinweis. Die Mindestgröße der Operationen beträgt
int
. Alsoshort
/char
werden befördert,int
bevor die Operation abgeschlossen ist.In all Ihren Ausdrücken
int
wird das zu a heraufgestuft,float
bevor die Operation ausgeführt wird. Das Ergebnis der Operation ist afloat
.quelle
char
Typ verwenden. Wenn der Wert von achar + char
zugewiesen istchar
, kann er einfach die Arithmetik in ausführenchar
und beispielsweise umbrechen. Wenn das Ergebnis jedoch zugewiesenint
ist, muss es die Arithmetik in einem Typ ausführen, der groß genug ist, um das richtige Ergebnis zu erhalten, wenn es größer als istCHAR_MAX
.((int) 4) - ((unsigned int) 5)
führt4294967295
zu 32-Bit-Ints und 32-Bit-Ints ohne Vorzeichen.Arithmetische Operationen mit
float
Ergebnissen infloat
.Für detailliertere Antwort. Schauen Sie sich an, was der Abschnitt §5 / 9 des C ++ - Standards sagt
quelle
double
noch istlong double
.long long
und hierunsigned long
nicht angesprochen.float
hat nicht genügend Bits in der Mantisse (24 Bit für IEEE-754 ) für ein 32-Bitint
, daher kann es zu Datenverlusten kommen. Ein 64-Bitdouble
sollte in Ordnung sein.Da die anderen Antworten nicht über die Regeln in C ++ 11 sprechen, ist hier eine. Aus dem C ++ 11-Standard (Entwurf n3337) §5 / 9 (betonte den Unterschied):
Siehe hier für eine Liste , die häufig aktualisiert wird .
quelle
Diese Antwort richtet sich größtenteils an einen Kommentar von @ RafałDowgird:
Beachten Sie, dass der C ++ - Standard die alles entscheidende "Als-ob" -Regel enthält. Siehe Abschnitt 1.8: Programmausführung:
Der Compiler kann eine
int
Größe von 8 Bit nicht festlegen , selbst wenn sie die schnellste wäre, da der Standard ein Minimum von 16 Bit vorschreibtint
.Daher könnte im Fall eines theoretischen Computers mit superschnellen 8-Bit-Operationen die implizite Heraufstufung zur
int
Arithmetik von Bedeutung sein. Bei vielen Operationen können Sie jedoch nicht feststellen, ob der Compiler die Operationen tatsächlich mit der Genauigkeit von a ausgeführtint
und dann in a konvertiert hatchar
, um sie in Ihrer Variablen zu speichern, oder ob die Operationen die ganze Zeit in char ausgeführt wurden.Stellen Sie sich zum Beispiel vor,
unsigned char = unsigned char + unsigned char + unsigned char
wo die Addition überlaufen würde (nehmen wir jeweils einen Wert von 200 an). Wenn Sie zu befördertint
würden, würden Sie 600 erhalten, die dann implizit in einunsigned char
Modulo 256 umgewandelt würden, was ein Endergebnis von 88 ergeben würde. Wenn Sie keine solchen Beförderungen durchführen würden, müssten Sie zwischen den ersten wechseln zwei Ergänzungen, die das Problem von200 + 200 + 200
auf reduzieren würden, nämlich144 + 200
344, was sich auf 88 reduziert. Mit anderen Worten, das Programm kennt den Unterschied nicht, so dass der Compiler das Mandat zur Ausführung von Zwischenoperationen ignorieren kann,int
wenn die Operanden haben ein niedrigerer Rang alsint
.Dies gilt im Allgemeinen für Addition, Subtraktion und Multiplikation. Dies gilt im Allgemeinen nicht für Division oder Modul.
quelle
Wenn Sie die vorzeichenlosen Typen ausschließen, gibt es eine geordnete Hierarchie: signiertes Zeichen, kurz, int, lang, lang, lang, float, doppelt, lang, doppelt. Zunächst wird alles, was oben vor int steht, in int konvertiert. Dann wird in einer binären Operation der Typ mit dem niedrigeren Rang in den Typ mit dem höheren Rang konvertiert, und die Ergebnisse sind der Typ mit dem höheren Rang. (Sie werden feststellen, dass aus der Hierarchie jedes Mal, wenn ein Gleitkomma- und ein Integraltyp beteiligt sind, der Integraltyp in den Gleitkommatyp konvertiert wird.)
Unsigned verkompliziert die Dinge ein wenig: Es stört das Ranking und Teile des Rankings werden implementiert. Aus diesem Grund ist es am besten, signierte und nicht signierte nicht im selben Ausdruck zu mischen. (Die meisten C ++ - Experten scheinen vorzeichenlose Vorgänge zu vermeiden, es sei denn, es handelt sich um bitweise Operationen. Dies wird zumindest von Stroustrup empfohlen.)
quelle
int
für eine Zahl, die niemals negativ sein muss, ist eine völlige Verschwendung von vollen 50% des verfügbaren Bereichs. Ich bin sicherlich kein Stroustrup, aber ich benutzeunsigned
standardmäßig undsigned
nur, wenn ich einen Grund habe.bool in_order(vector<T> vec) { for ( int i = 0; i < size() - 1; ++i) { if (vec[i + 1] < vec[i]) return false; } return true;
und dann wären Sie verärgert, wenn Sie feststellen würden, dass es für leere Vektoren abstürzt, weil size () - 1 18446744073709551615 zurückgibt.Meine Lösung zum Problem bekam WA (falsche Antwort), dann änderte es einen
int
zulong long int
und es gab AC (nehmen) . Zuvor habe ich versuchtlong long int += int * int
, und nachdem ich es korrigiert habelong long int += long long int * int
. Googeln habe ich mir ausgedacht,1. Arithmetische Umrechnungen
Bedingungen für die Typkonvertierung:
Bedingungen erfüllt ---> Konvertierung
Jeder Operand ist vom Typ long double . ---> Ein anderer Operand wird in den Typ long double konvertiert .
Die vorhergehende Bedingung ist nicht erfüllt und jeder Operand ist vom Typ double . ---> Ein anderer Operand wird in den Typ double konvertiert .
Vorherige Bedingungen sind nicht erfüllt und jeder Operand ist vom Typ float . ---> Ein anderer Operand wird in den Typ float konvertiert .
Vorherige Bedingungen nicht erfüllt (keiner der Operanden ist vom schwebenden Typ). ---> Integrale Promotions werden für die Operanden wie folgt durchgeführt:
2. Ganzzahlige Konvertierungsregeln
Ganzzahlige Typen, die kleiner als int sind, werden heraufgestuft, wenn eine Operation an ihnen ausgeführt wird. Wenn alle Werte des ursprünglichen Typs als int dargestellt werden können, wird der Wert des kleineren Typs in ein int konvertiert. Andernfalls wird es in ein vorzeichenloses int konvertiert. Ganzzahlige Heraufstufungen werden als Teil der üblichen arithmetischen Konvertierungen auf bestimmte Argumentausdrücke angewendet. Operanden der unären Operatoren +, - und ~; und Operanden der Schichtoperatoren.
Integer Conversion Rank:
long long int
ist größer als der Rang vonlong int
, der größer sein soll als der Rang vonint
, der größer sein soll als der Rang vonshort int
, der größer sein soll als der Rang vonsigned char
.char
soll dem Rang vonsigned char
und entsprechenunsigned char
.Übliche arithmetische Umrechnungen:
quelle
In Kapitel 4 geht es um Conversions, aber ich denke, Sie sollten sich hauptsächlich für Folgendes interessieren:
4.5 Integrale Promotions [conv.prom]
Ein Wert vom Typ char, ein vorzeichenbehaftetes Zeichen, ein vorzeichenloses Zeichen, ein kurzes int oder ein vorzeichenloses kurzes int kann in einen r-Wert vom Typ int konvertiert werden, wenn int alle Werte des Quelltyps darstellen kann. Andernfalls
kann der Quell-r-Wert in einen r-Wert vom Typ unsigned int konvertiert werden.
Ein r-Wert vom Typ wchar_t (3.9.1) oder ein Aufzählungstyp (7.2) kann in einen r-Wert des ersten
der folgenden Typen konvertiert werden, der alle Werte des zugrunde liegenden Typs darstellen kann: int, unsigned int,
long oder unsigned lange.
Ein r-Wert für ein integrales Bitfeld (9.6) kann in einen r-Wert vom Typ int konvertiert werden, wenn int alle
Werte des Bitfelds darstellen kann . Andernfalls kann es in unsigned int konvertiert werden, wenn unsigned int wiedergeben kann
Senden Sie alle Werte des Bitfelds erneut. Wenn das Bitfeld noch größer ist, gilt keine integrale Heraufstufung. Wenn das
Bitfeld einen Aufzählungstyp hat, wird es für Heraufstufungszwecke wie jeder andere Wert dieses Typs behandelt.
Ein Wert vom Typ bool kann in einen Wert vom Typ int konvertiert werden, wobei false zu Null und true
zu Eins wird.
Diese Conversions werden als integrale Aktionen bezeichnet.
4.6 Gleitkomma- Heraufstufung [conv.fpprom]
Ein Wert vom Typ float kann in einen Wert vom Typ double konvertiert werden. Der Wert bleibt unverändert.
Diese Konvertierung wird als Gleitkomma-Promotion bezeichnet.
Daher sind alle Konvertierungen mit float - das Ergebnis ist float.
Nur derjenige, an dem beide int beteiligt sind - das Ergebnis ist int: int / int = int
quelle
Der Typ des Ausdrucks wird in den größten von beiden konvertiert, wenn nicht beide Teile vom gleichen Typ sind . Das Problem hierbei ist zu verstehen, welches größer als das andere ist (es hat nichts mit der Größe in Bytes zu tun).
In Ausdrücken, an denen eine reelle Zahl und eine Ganzzahl beteiligt sind, wird die Ganzzahl zur reellen Zahl heraufgestuft. In int + float ist der Typ des Ausdrucks beispielsweise float.
Der andere Unterschied hängt mit der Fähigkeit des Typs zusammen. Beispielsweise ergibt sich ein Ausdruck mit einem int und einem long int vom Typ long int.
quelle
long
ist a "größer" als a,float
aber was ist die Art vonlong
+float
?Vorbehalt!
Die Konvertierungen erfolgen von links nach rechts.
Versuche dies:
quelle
j + i * k
würde in 101 führen.