Newsgroup: it.comp.lang.c
Titolo: unsigned -> nirvana

Forse ci sono...
i numeri interi, signed o unsigned, vengono rappresentati in memoria in
questo stesso modo:
*) i numeri positivi sono semplici numeri binari ad n bit;
*) nei numeri negativi, il bit più significativo viene messo a 1 e indica
il segno, gli altri n-1 bit contengono il complemento a due del modulo del
numero.
Oppure: trasformo il numero negativo (ad esempio -1) in positivo (1), lo
trasformo in binario (0...0(n-1 volte)1) e poi faccio il complemento a
due.
Questo metodo garantisce continuità andando dai numeri negativi a quelli
positivi e si può facilmente convertire variabili signed in unsigned.
Nel programma
	int main(void)
		{
			unsigned char i = -1;
			printf("%d", i);
		}
in memoria la variabile i viene rappresentata, quindi, come 11111111.
L'istruzione printf("%d", i); si aspetta un argomento (signed) int e,
quindi, converte (momentaneamente) i in un intero a 32 bit (nel mio caso).
Essendo i un unsigned vengono aggiunti 24 zeri a sinistra (se i fosse
stato signed, vi sarebbero stati tanti 0 o tanti 1 in base al bit più
significativo - vedi verifica.c).
Stampando il numero come intero con segno, si ottiene, quindi, 255
(0...0(24 volte)11111111).
Idem con il programma
	int main(void)
	{
		unsigned short i = -1;
		printf("%d", i);
	}
Con il programma
	int main(void)
	{
		unsigned int i = -1;
		printf("%d", i);
	}
la variabile i viene rappresentata in memoria come 1...1(32 volte). Printf
stampa i come intero con segno... risultato -1. Utilizzando printf("%u",
i); il numero 1...1(32 volte) viene stampato come intero senza segno,
quindi 4 miliardi etc. etc.
Idem con il programma
	int main(void)
	{
		unsigned long i = -1;
		printf("%d", i);
	}
Cosa ne pensate? avete già detto tutto quello che c'era da dire? avete
ragione... :-) vi ringrazio comunque...
Alla prossima.
Angelo
PS. verifica.c
#include <stdio.h>
int main(void)
	{
		signed char i = -1;
		unsigned char j = -1;
 
		putchar('\n');
		printf("    signed char i = -1 -> %%u %10u %%d %4d\n", i, i);
		printf("unsigned char j = -1 -> %%u %10u %%d %4d\n\n", j, j); 
		return 0;
}

 due.
cosi' e' piu' giusto.
aspetto smentite, sono cocciuto!
ciao
donCiccio

ragione... :-) vi ringrazio comunque...
E' errato usare %d per stampare un unsigned long.

Per sapere quanto vale un signed si può fare in due modi: o si esegue il 
complemento a 1 di tutti i bit tranne quello più significativo che 
rappresenta il segno(1 = neg, 0 = pos) e poi si somma 1, oppure si legge 
il numero signed comprensivo della cifra + significativa e lo si 
converte così com'è in decimale e si conta quanto manca per raggiungere 
il numero massimo raggiungibile con quel numero di bit. In pratica col 
secondo metodo converti il numero immediatamente ed esegui la 
sottrazione tra il max numero rappresentabile con tutti i bit 
dell'intero col sengo che ti interessa (compreso quello di segno!) e il 
tuo numero decimale convertito, es:
10010      signed, se lo converto è 18;
            con 5 bit riesco a rappresentare 32 percui faccio:
32-18=14   che col segno del bit + significativo fa -14.
Se usi il metodo classico sarebbe:
10010      signed da complementare a uno:
  1101 +    poi sommo uno:
     1 =
-------
  1110      che è appunto 14 col segno meno è -14.
Spero di non aver sbagliato niente, sono andato a memoria e non è che io 
ne abbia molta, però i conti tornano tutti!
CIAO___________________________
               ALFREDO DONATI
¤===¤===¤===¤===¤===¤===¤===¤===¤===¤===¤
  \  Undergraduate Student of Computer  /
   \ Science at University of Bologna  /
    ¤==¤===¤===¤===¤===¤===¤===¤===¤==¤
     \    
www.cs.unibo.it/~adonati
   /
      \     
ado...@cs.unibo.it
     /
       \      ICQ# 111878362       /
        ¤===¤===¤====¤====¤===¤===¤
I don't have a license to kill.
I have a learner's permit.