Nein wirklich, wann kommt es tatsächlich zur Gleitkomma-Promotion?

8

Von dieser anderen FRAGE wird gesprochen wie Bjarne Stroustrup sagte, dass genauso wie ganzzahlige Datentypen, die enger als ein int (zB short ) sind, zu einem int befördert werden, werden float s zu einem double hochgestuft. Im Gegensatz zur Erweiterung von Integralen, die kleiner als int sind, erfolgt Gleitkomma-Hochstufung jedoch nicht auf die gleiche Weise, sondern stattdessen an einer anderen Stelle.

Ich weiß, wenn Sie float + double berechnen würden, würde float in ein double konvertiert, bevor der binäre Operator ( + ) angewendet wird. Dies ist jedoch nicht Gleitkomma-Promotion gemäß Learncpp.com . Dies ist übliche arithmetische Konvertierung .

Wann findet tatsächlich eine Gleitkomma-Promotion statt?

    
Bryan 27.05.2015, 18:40
quelle

2 Antworten

13

Es gibt so etwas wie "Floating Point-Promotion" von float bis double pro [conv.fpprom].

  

Ein Prvalue vom Typ float kann in einen prvalue vom Typ double konvertiert werden. Der Wert ist unverändert.

     

Diese Konvertierung wird als Gleitkomma-Promotion bezeichnet.

Die Antworten auf die verknüpfte Frage sind korrekt. Diese Heraufstufung sollte nicht automatisch erfolgen, wenn zwei float s hinzugefügt werden, da die üblichen arithmetischen Konvertierungen keine Fließkomma-Operanden fördern.

Gleitkomma-Hochstufung tritt auf , wenn ein float als Operand an eine Ellipse übergeben wird, wie in printf . Deshalb druckt der Formatbezeichner %f entweder ein float oder ein double : Wenn Sie ein float übergeben, erhält die Funktion tatsächlich ein double , das Ergebnis der Aktion.

Die Existenz der Gleitkomma-Heraufstufung ist auch bei der Überladungsauflösung wichtig, da integrale Beförderungen und Gleitkomma Beförderungen einen besseren impliziten Umwandlungsrang haben als integrale Umwandlungen , Fließkomma Konvertierungen und Floating-Integral Konvertierungen .

Beispiel 1:

%Vor%

Dies ruft void f(double) auf, da das Hochstufen auf double besser ist als die Umwandlung in long double . Betrachten Sie das vielleicht überraschende Beispiel 2:

%Vor%

Das ist mehrdeutig. Die Conversion von float nach long double ist nicht besser als die Conversion von float nach int , da beide keine Promotions sind.

Beispiel 3:

%Vor%

Dies ruft operator float auf und fördert dann den resultierenden float -Wert auf double , um d zu initialisieren.

    
Brian 27.05.2015, 18:57
quelle
6

Der primäre (vielleicht einzige) Zeitpunkt, zu dem Gleitkomma-Promotions angewendet werden, ist das Übergeben eines Arguments an eine variadische Funktion (z. B. printf ).

In diesem Fall gelten die üblichen arithmetischen Konvertierungen nicht (sie dienen dazu, einen gemeinsamen Typ zwischen zwei Operanden in einem Ausdruck zu finden).

Der relevante Teil des Standards ist [expr.call] / 7 (mindestens ab N4296):

  

Wenn für ein gegebenes Argument kein Parameter vorhanden ist, wird das Argument so übergeben, dass die empfangende Funktion den Wert des Arguments durch Aufruf von va_arg (18.10) erhalten kann.   
[...]
  Wenn das Argument einen Integral- oder Aufzählungstyp aufweist, der den Integral-Promotions (4.5) unterliegt, oder ein Gleitkommatyp, der der Gleitkomma-Heraufstufung (4.6) unterliegt, wird der Wert des Arguments vor dem Aufruf in den Typ mit dem Status Promated konvertiert .

    
Jerry Coffin 27.05.2015 18:47
quelle

Tags und Links