2015-05-27 17 views
8

Da quest'altra QUESTION si parla di come Bjarne Stroustrup ha detto che proprio come integrali tipi di dati più strette di un int (per esempio short) vengono promossi ad un int, float s sono promossi ad un double. Tuttavia, a differenza dell'ampliamento degli integrali più stretto di uno promozione in virgola mobile, non si verifica lo stesso modo, ma si verifica altrove.No, quando si realizza effettivamente la promozione floating point?

So che se si dovesse calcolare il float + doublefloat sarebbe convertito double prima di applicare l'operatore binario (+). Tuttavia, questa non è promozione in virgola mobile secondo Learncpp.com. Questa è conversione aritmetica usuale.

Quando si verifica effettivamente la promozione floating point?

+1

leggi i commenti e le risposte vedrai che il libro di Bjarne è in errore. –

+0

possibile duplicato di [promozione floating point: stroustrup vs compilatore - chi ha ragione?] (Http://stackoverflow.com/questions/17215484/floating-point-promotion-stroustrup-vs-compiler-who-is-right) –

+0

@RichardHodges Ho letto i commenti. Anche se quel piccolo estratto è stato tolto dal libro, questo non mi dice se la promozione in virgola mobile è stata tolta dalla lingua. Non ho ancora idea di quando possa verificarsi la promozione floating point. – Bryan

risposta

13

C'è una cosa come "promozione in virgola mobile" di float per double per [conv.fpprom].

Un prvalue di tipo float può essere convertito in un prvalue di tipo double. Il valore è invariato.

Questa conversione è denominata promozione in virgola mobile.

Le risposte alla domanda collegata sono corrette. Questa promozione non dovrebbe verificarsi automaticamente quando si aggiungono due float poiché le normali conversioni aritmetiche non promuovono gli operandi in virgola mobile.

floating point promozione fa verifica quando passa un float come operando ad un'ellisse, come in printf.Ecco perché lo specificatore di formato %f stampa uno float o uno double: se si passa uno float, la funzione riceve effettivamente un double, il risultato della promozione.

L'esistenza della promozione virgola mobile è anche importante per la risoluzione di sovraccarico, perché integrali promozioni e virgola mobile promozioni hanno rango migliore conversione implicito che integrali conversioni, virgola mobile conversioni, e galleggianti integrale conversioni.

Esempio 1:

void f(double); 
void f(long double); 
f(0.0f); 

Ciò richiede void f(double) in quanto la promozione in double è meglio che la conversione a long double. Al contrario, consideriamo questo esempio forse sorprendente 2:

void f(long double); 
void f(int); 
f(0.0f); 

Questo è ambiguo. La conversione da float a long double non è migliore della conversione da float a int poiché non sono entrambe promozioni.

Esempio 3:

struct S { 
    operator float(); 
    operator int(); 
}; 
double d = S(); 

Ciò richiede operator float e quindi promuove la risultante float valore double per inizializzare d.

+0

La tua risposta è così dettagliata e ha ottimi esempi. Otterrò completamente la promozione in virgola mobile ora. Grazie mille! – Bryan

6

Il tempo primario (forse unico) in cui vengono applicate le promozioni in virgola mobile è quando si passa un argomento a una funzione variadica (ad es., printf).

In questo caso, le normali conversioni aritmetiche non si applicano (sono per trovare un tipo comune tra due operandi in un'espressione).

La parte rilevante dello standard è [expr.call]/7 (almeno di N4296):

Quando non esiste un parametro per un dato argomento, l'argomento viene passato in modo tale che la funzione ricevente possa ottenere il valore dell'argomento invocando va_arg (18.10).
[...]
Se l'argomento ha un tipo integrale o di enumerazione soggetto alle promozioni integrali (4.5) o un tipo a virgola mobile soggetto alla promozione in virgola mobile (4.6), il valore dell'argomento viene convertito nel tipo promosso prima della chiamata.

+0

Stai parlando di conversione di tipo? So che la conversione di tipo avviene se si passa un float a una funzione variadica che ha un doppio come parametro. Non credo che la conversione di tipo e la promozione in virgola mobile siano la stessa cosa. Se intendi qualcos'altro, ti prego di elaborare? – Bryan

+0

Oh! Stai parlando di ellissi. Dove il parametro può essere qualsiasi valore e qualsiasi numero di valori. Quindi è qui che può accadere la promozione floating point. Grazie! – Bryan

Problemi correlati