Warum printf () einen Float zu einem Double hochlädt?

19

Von einer früheren Frage :

  

Wenn Sie versuchen, ein float an printf zu übergeben, wird es zu double hochgestuft.   bevor printf es empfängt

printf() ist eine variadische Funktion oder? Also fördert eine variadic Funktion ein float Argument zu einem double , bevor es übergeben wird?

    
Community 22.01.2015, 19:57
quelle

4 Antworten

20

Ja, Float-Argumente für variadic-Funktionen werden zu double hochgestuft.

Der Entwurf C99 Standard Abschnitt 6.5.2.2 Funktionsaufrufe sagt :

  

[...] und Argumente, die   have type float wird zu double hochgestuft. Diese werden als Standardargument bezeichnet   Werbeaktionen [...]

aus dem Entwurf des C ++ - Standards Abschnitt 5.2.2 Funktionsaufruf:

  

[...] ein Fließkommatyp, der dem Fließkomma unterliegt   promotion (4.6) wird der Wert des Arguments in   Typ vor dem Aufruf. [...]

und Abschnitt 4.6 :

  

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

cppreference deckt die Standardkonvertierungen für variadic Funktion in C ++ gut:

  
  • std :: nullptr_t wird in void *
  • konvertiert   
  • float-Argumente werden in double wie in Floating-Point-Promotion konvertiert
  •   
  • bool-, char-, short- und unscoped-Enumerationen werden wie in ganzzahlige Heraufstufungen
  • in int-Typen oder breitere Integer-Typen konvertiert   

Wir können in C und vermutlich in C ++ sehen, dass diese Konvertierung für die Kompatibilität mit K & amp; RC von Begründung für internationale Standard-Programmiersprachen-C ( Hervorhebung von mir ):

  

Aus Gründen der Kompatibilität mit der bisherigen Vorgehensweise werden alle Argumentaktionen wie folgt durchgeführt   in K & amp; R in Ermangelung einer Prototyp-Deklaration beschrieben, einschließlich   die nicht immer wünschenswerte Promotion von float zu verdoppeln.

    
Shafik Yaghmour 22.01.2015, 20:02
quelle
14

Was den warum Teil der Frage anbelangt, ist es einfach: Die C (und C ++) Standards betrachten double als den "Standard" Gleitkommatyp. Nicht float (was bei vielen von uns Programmierern standardmäßig bei der Verwendung von Gleitkommazahlen ist).

Dies kann durch Beobachtung gesehen werden:

  1. 3.14 ist ein double (wenn du ein float willst, musst du einen zusätzlichen Schritt machen und ein f anhängen)
  2. Die standardmäßigen mathematischen Funktionen verwenden standardmäßig double (zB sin() benötigt double ; wenn Sie float wollen, müssen Sie sinf() verwenden)

Damit erscheint es "natürlicher", dass ein float in einem variadischen Funktionsaufruf zu double hochgestuft wird, da double der "natürliche" Standard in der Sprache ist.

    
Cornstalks 22.01.2015 20:07
quelle
13

Gegeben sei ein Funktionsprototyp, der Typ float wird nur dann automatisch befördert, wenn er in ablaufenden Argumenten verwendet wird. Funktionsdruck verwendet diese:

%Vor%

1 (Zitiert nach: ISO / IEC 9899: 201x 6.5.2.2 Funktionsaufrufe)
6. Die Integer-Promotions werden für jedes Argument ausgeführt, und Argumente, die have type float wird zu double hochgestuft. Diese werden als Standardargument bezeichnet Werbeaktionen.
7. Das Standardargument Aktionen werden für nachfolgende Argumente ausgeführt.

    
2501 22.12.2016 13:11
quelle
11

Weil der Standard (C99 oder C11 ) dies sagt. Siehe answer by 2501 .

Dafür gibt es mehrere pragmatische Gründe: Geschichte (die ersten Implementierungen von C wurden für die Systemprogrammierung verwendet, wobei Fließkommaoperationen keine Rolle spielen), und die Tatsache, dass es aktuell ist (Tablet, Desktop, Server ...) Prozessoren, arithmetische Operationen auf double sind ungefähr so ​​effizient wie float (aber einige billige Mikrocontroller haben keine FPU oder können nur float per Hardware hinzufügen und benötigen eine Bibliothek für jede Operation auf double ) . Ich denke, dass eine solche Regel endlich einfachere Aufrufkonventionen und ABI s.

Denken Sie an float als eine Art short double (was natürlich illegal in C ist). A float ist vor allem nützlich, wenn Sie Speicher komprimieren müssen (und den Verlust der Genauigkeit leisten können). Siehe auch Ссылка für mehr.

    
Basile Starynkevitch 22.12.2016 13:03
quelle

Tags und Links