Promozioni del tipo di dati durante le operazioni aritmetiche:-1 < (int unsinged) 1 == falso
-
29-09-2019 - |
Domanda
main() {
if ( -1 < (unsigned char) 1 )
printf("less than");
else
printf("NOT less than");
}
Stampe less than
.Perché, (unsigned char) 1
viene convertito in (signed char) 1
poi: (signed) -1 < (signed) 1
, quindi l'output è less than
.
Ma se cambio il codice sopra A if ( (-1 < (unsigned int) 1 )
quindi l'output è NOT less than
.
Quindi è ovvio che quando cambio unsigned char in unsigned int:
- (signed) -1 viene convertito in unsigned int [sta accadendo esattamente il contrario]
- poiché -1 è memorizzato come complemento di 2 di 1;il modello di bit viene valutato come 255 (probabilmente)
- quindi 255 < 1 valuterà falso e altrimenti verrà eseguito.
- anche se sostituisci
int a = -1;
al posto di '-1' stesso risultato
Domande:
durante l'aritmetica con segno e senza segno... come essere sicuri se firmato verrà convertito in senza segno o viceversa.
perché la conversione per l'aritmetica è diversa tra caratteri senza segno e caratteri:apparentemente unsigned viene convertito insigned e unsigned int e int :apparentemente firmato si converte in senza segno
PS:So che questo non dipende dal compilatore... quindi non dire che lo sia.
Soluzione
Le regole sono le seguenti:
6.3.1.8 conversioni aritmetiche abituali
...
Altrimenti, promozioni interi vengono eseguite su entrambi gli operandi. Poi il seguenti regole vengono applicate ai operandi promossi:
- Se entrambi gli operandi sono dello stesso tipo, è necessario allora nessuna ulteriore conversione.
- Altrimenti, se entrambi gli operandi hanno firmato integer tipi o entrambi avere tipi interi senza segno, l'operando con il tipo di minore rango conversione integer viene convertito nel tipo dell'operando con maggiore rango.
- Altrimenti, se l'operando che ha senza segno tipo intero ha rango maggiore o uguale al rango di tipo dell'altro operando, quindi l'operando con il tipo integer firmato viene convertito al tipo dell'operando di tipo intero senza segno.
- In caso contrario, se il tipo dell'operando di tipo intero con segno può rappresentare tutti i valori del tipo dell'operando con tipo intero senza segno quindi l'operando con tipo intero senza segno viene convertito nel tipo dell'operando con intero con segno tipo.
- Altrimenti, entrambi gli operandi vengono convertiti nel tipo intero senza segno corrispondente al tipo dell'operando con firmati integer tipo.
Le regole poi lavorare come segue:
-
-1 < (unsigned char) 1
Prima ambo vengono convertiti in int (perché un int può rappresentare tutti i valori di char senza segno). Quindi il confronto viene effettuato su questi tipi firmati. Regola 1 viene quindi utilizzato. Il confronto ha esito positivo.
-
-1 < (unsigned int) 1
Un int non può rappresentare tutti i valori di un unsigned int modo regola 3 è utilizzato e il numero intero firmato viene convertito in un numero intero senza segno (UINT_MAX - 1). Il confronto ora non riesce.
Altri suggerimenti
Questo è dovuto a promozioni intere.Entrambi gli argomenti possono essere rappresentati come int, quindi vengono convertiti in int.
ISO C 6.3.1.1, paragrafo 2:
Se un int può rappresentare tutti i valori del tipo originale, il valore viene convertito in un int;in caso contrario, viene convertito in un int senza segno.Queste sono chiamate promozioni interi.48) Tutti gli altri tipi sono invariati dalle promozioni interi.