Promozioni del tipo di dati durante le operazioni aritmetiche:-1 < (int unsinged) 1 == falso

StackOverflow https://stackoverflow.com/questions/3900385

  •  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:

  1. durante l'aritmetica con segno e senza segno... come essere sicuri se firmato verrà convertito in senza segno o viceversa.

  2. 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.

È stato utile?

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:

     
      
  1. Se entrambi gli operandi sono dello stesso tipo, è necessario allora nessuna ulteriore conversione.
  2.   
  3. 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.
  4.   
  5. 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.
  6.   
  7. 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.
  8.   
  9. Altrimenti, entrambi gli operandi vengono convertiti nel tipo intero senza segno corrispondente al tipo dell'operando con firmati integer tipo.
  10.   

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top