c++ - collegare tabella excel ad access tra



Regole di conversione del tipo implicito in operatori C++ (6)

Voglio essere migliore di sapere quando dovrei fare il cast. Quali sono le regole implicite di conversione del tipo in C ++ quando si aggiunge, si moltiplica, ecc. Ad esempio,

int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?

e così via ...

L'espressione sarà sempre valutata come il tipo più preciso? Le regole differiscono per Java? Per favore correggimi se ho formulato questa domanda in modo impreciso.

https://ffff65535.com


Avvertimento!

Le conversioni avvengono da sinistra a destra.

Prova questo:

int i = 3, j = 2;
double k = 33;
cout << k * j / i << endl; // prints 22
cout << j / i * k << endl; // prints 0

Il tipo di espressione, quando non entrambe le parti sono dello stesso tipo, verrà convertito nel più grande di entrambi. Il problema qui è capire quale è più grande dell'altro (non ha nulla a che fare con le dimensioni in byte).

Nelle espressioni in cui sono coinvolti un numero reale e un numero intero, il numero intero verrà promosso al numero reale. Ad esempio, in int + float, il tipo dell'espressione è float.

L'altra differenza è legata alla capacità del tipo. Ad esempio, un'espressione che coinvolge un int lungo e int sarà il risultato di tipo long int.


La mia solution al problem ottenuto WA (risposta errata), quindi ho cambiato uno di int a long long int e ha dato AC(accept) . In precedenza, stavo cercando di fare long long int += int * int , e dopo averlo rettificato a long long int += long long int * int . Ho cercato su Google,

1. Conversioni aritmetiche

Condizioni per la conversione del tipo:

Condizioni soddisfatte ---> Conversione

  • Entrambi gli operandi sono di tipo long double . ---> L'altro operando viene convertito in tipo long double .

  • Condizione precedente non soddisfatta e entrambi gli operandi sono di tipo doppio . ---> L'altro operando viene convertito in tipo double .

  • Condizioni precedenti non soddisfatte e entrambi gli operandi sono di tipo flottante . ---> L'altro operando viene convertito in tipo float .

  • Condizioni precedenti non soddisfatte (nessuno degli operandi è di tipo floating). ---> Le promozioni integrali vengono eseguite sugli operandi come segue:

    • Se uno degli operandi è di tipo unsigned long , l'altro operando viene convertito in type unsigned long .
    • Se la condizione precedente non viene soddisfatta e se uno degli operandi è di tipo long e l'altro di tipo unsigned int , entrambi gli operandi vengono convertiti in type unsigned long .
    • Se le due condizioni precedenti non sono soddisfatte e se uno degli operandi è di tipo lungo , l'altro operando viene convertito in tipo long .
    • Se le tre condizioni precedenti non sono soddisfatte e se uno degli operandi è di tipo unsigned int , l'altro operando viene convertito in type unsigned int .
    • Se nessuna delle condizioni precedenti è soddisfatta, entrambi gli operandi vengono convertiti in tipo int .

2. Regole di conversione intera

  • Promozioni intere:

I tipi interi più piccoli di int vengono promossi quando viene eseguita un'operazione su di essi. Se tutti i valori del tipo originale possono essere rappresentati come int, il valore del tipo più piccolo viene convertito in un int; in caso contrario, viene convertito in un int unsigned. Le promozioni intere vengono applicate come parte delle normali conversioni aritmetiche a determinate espressioni di argomento; operandi degli operatori unari +, -, e ~; e operandi degli operatori di turno.

  • Rango di conversione intero:

    • Non sono ammessi due tipi interi con segno uguale, anche se hanno la stessa rappresentazione.
    • Il rango di un tipo intero con segno deve essere maggiore del grado di qualsiasi tipo di intero con segno con minore precisione.
    • Il grado di long long int sarà maggiore del rank di long int , che sarà maggiore del rank di int , che sarà maggiore del rank di short int , che sarà maggiore del rank di signed char .
    • Il rango di qualsiasi tipo intero senza segno è uguale al rango del corrispondente tipo di intero con segno, se presente.
    • Il rango di qualsiasi tipo intero standard deve essere maggiore del rango di qualsiasi tipo intero esteso con la stessa larghezza.
    • Il grado di char equivale al grado del signed char e del unsigned char .
    • Il rango di qualsiasi tipo di intero con segno esteso rispetto ad un altro tipo di intero con segno esteso con la stessa precisione è definito dall'implementazione ma è comunque soggetto alle altre regole per determinare il rango di conversione dei numeri interi.
    • Per tutti i tipi interi T1, T2 e T3, se T1 ha rango maggiore di T2 e T2 ha rango maggiore di T3, quindi T1 ha rango maggiore di T3.
  • Usuali conversioni aritmetiche:

    • Se entrambi gli operandi hanno lo stesso tipo, non è necessaria alcuna ulteriore conversione.
    • Se entrambi gli operandi sono dello stesso tipo intero (firmato o non firmato), l'operando con il tipo di rango di conversione intero minore viene convertito nel tipo dell'operando con un rango più grande.
    • Se l'operando che ha un numero intero senza segno ha rank superiore o uguale al rank del tipo di un altro operando, l'operando con tipo intero con segno viene convertito nel tipo dell'operando con tipo intero senza segno.
    • Se il tipo dell'operando con tipo intero con segno può rappresentare tutti i valori del tipo dell'operando con tipo intero senza segno, l'operando con tipo intero senza segno viene convertito nel tipo dell'operando con tipo intero con segno.
    • In caso contrario, entrambi gli operandi vengono convertiti nel tipo intero senza segno corrispondente al tipo di operando con tipo intero con segno. Operazioni specifiche possono aggiungere o modificare la semantica delle solite operazioni aritmetiche.

Le operazioni aritmetiche che coinvolgono il float risultano in float .

int + float = float
int * float = float
float * int = float
int / float = float
float / int = float
int / int = int

Per una risposta più dettagliata. Guarda cosa dice la sezione §5 / 9 dello standard C ++

Molti operatori binari che si aspettano operandi di tipo aritmetico o di enumerazione causano conversioni e producono tipi di risultato in modo simile. Lo scopo è quello di produrre un tipo comune, che è anche il tipo del risultato .

Questo modello è chiamato le solite conversioni aritmetiche, che sono definite come segue:

- Se uno degli operandi è di tipo long double, l'altro deve essere convertito in long double.

- Altrimenti, se uno degli operandi è doppio, l'altro deve essere convertito in doppio.

- Altrimenti, se uno degli operandi è mobile, l'altro deve essere convertito in float.

- In caso contrario, le promozioni integrali (4.5) devono essere eseguite su entrambi gli operandi.54)

- Quindi, se uno degli operandi è senza firma l'altro deve essere convertito in unsigned long.

- Altrimenti, se un operando è un long int e l'altro unsigned int, allora se un long int può rappresentare tutti i valori di un unsigned int, il unsigned int deve essere convertito in un long int; altrimenti entrambi gli operandi devono essere convertiti in unsigned long int.

- Altrimenti, se uno degli operandi è lungo, l'altro deve essere convertito in long.

- Altrimenti, se uno degli operandi non è firmato, l'altro deve essere convertito in non firmato.

[Nota: altrimenti, l'unico caso rimanente è che entrambi gli operandi siano int]


Poiché le altre risposte non parlano delle regole in C ++ 11 eccone una. Dalla norma C ++ 11 (bozza n. 3337) § 5/9:

Questo modello è chiamato le solite conversioni aritmetiche , che sono definite come segue:

- Se uno degli operandi è di tipo enumerato con scope, non vengono eseguite conversioni; se l'altro operando non ha lo stesso tipo, l'espressione è mal formata.

- Se uno degli operandi è di tipo long double, l'altro deve essere convertito in long double.

- Altrimenti, se uno degli operandi è doppio, l'altro deve essere convertito in doppio.

- Altrimenti, se uno degli operandi è mobile, l'altro deve essere convertito in float.

- Altrimenti, le promozioni integrali devono essere eseguite su entrambi gli operandi. Quindi le seguenti regole devono essere applicate agli operandi promossi:

- Se entrambi gli operandi hanno lo stesso tipo, non è necessaria alcuna ulteriore conversione.

- Altrimenti, se entrambi gli operandi hanno tipi interi con segno o entrambi hanno tipi interi senza segno, l'operando con il tipo di rango di conversione intero minore deve essere convertito nel tipo dell'operando con grado maggiore.

- Altrimenti, se l'operando che ha un numero intero senza segno ha rank superiore o uguale al rank del tipo di un altro operando, l'operando con tipo intero con segno deve essere convertito nel tipo dell'operando con tipo intero senza segno.

- Altrimenti, se il tipo dell'operando con tipo intero con segno può rappresentare tutti i valori del tipo dell'operando con tipo intero senza segno, l'operando con tipo intero senza segno deve essere convertito nel tipo dell'operando con tipo intero con segno.

- Altrimenti, entrambi gli operandi devono essere convertiti nel tipo intero senza segno corrispondente al tipo di operando con tipo intero con segno.

Vedi here per un elenco che viene frequentemente aggiornato.


Questa risposta è diretta in gran parte ad un commento fatto da @ RafałDowgird:

"La dimensione minima delle operazioni è int". - Questo sarebbe molto strano (che dire delle architetture che supportano in modo efficiente le operazioni char / short?) Questo è veramente nelle specifiche del C ++?

Tieni presente che lo standard C ++ ha l'importantissima regola "as-if". Vedi sezione 1.8: Esecuzione del programma:

3) Questa disposizione viene talvolta chiamata la regola "as-if", in quanto un'implementazione è libera di ignorare qualsiasi requisito dello Standard finché il risultato è come se il requisito fosse stato rispettato, per quanto è possibile determinare dall'osservabile comportamento del programma.

Il compilatore non può impostare un int per avere una dimensione di 8 bit, anche se fosse il più veloce, dal momento che lo standard impone un int minimo di 16 bit.

Pertanto, nel caso di un computer teorico con operazioni a 8 bit superveloci, la promozione implicita a int per l'aritmetica potrebbe avere importanza. Tuttavia, per molte operazioni, non è possibile stabilire se il compilatore ha effettivamente eseguito le operazioni nella precisione di un int e successivamente convertito in un char per archiviare nella variabile, o se le operazioni sono state eseguite in char tutte insieme.

Ad esempio, si consideri il unsigned char = unsigned char + unsigned char + unsigned char , dove l'addizione si sovrapporrà (assumiamo un valore di 200 per ciascuno). Se promossi a int , int 600, che verrebbero quindi convertiti implicitamente in un unsigned char , che avvolgerebbe il modulo 256, ottenendo così un risultato finale di 88. Se non facessi tali promozioni, dovresti concludere tra le prime due aggiunte, che ridurrebbe il problema da 200 + 200 + 200 a 144 + 200 , che è 344, che si riduce a 88. In altre parole, il programma non conosce la differenza, quindi il compilatore è libero di ignorare il mandato per eseguire operazioni intermedie in int se gli operandi hanno un ranking inferiore a int .

Questo è vero in generale di addizione, sottrazione e moltiplicazione. Non è vero in generale per la divisione o il modulo.





implicit