SCALETTA LEZIONE SERT E9 -- 29 novembre 2012 *** Stampa di numeri in decimale 1 Per scrivere un numero in decimale l'algoritmo e' piu' complesso: Si divide ripetutamente per 10, prendendo nota dei resti, fino a quando il divisore non diventa zero Si stampano i resti in ordine LIFO, dall'ultimo al primo 1.1 Scrivere la funzione putu() per stampare un unsigned long in decimale 1.1.1 Prima versione con modulo e divisione intera +----------------------------------------------------------+ |void putu(unsigned long v) | |{ | | char buf[11]; /* log10(2^32-1)=9.63 (+1 for '\0') */ | | int i, r; | | if (v < 10UL) { | | putc(v + '0'); | | return; | | } | | i = 10; | | buf[i] = '\0'; | | while (v != 0) { | | r = v % 10; | | v = v / 10; | | buf[--i] = (char)('0'+r); | | } | | puts(buf+i); | |} | +----------------------------------------------------------+ 1.1.2 Provare a compilare: non funziona! uart1.o: In function `putu': uart1.c:(.text+0x120): undefined reference to `__aeabi_uidiv' uart1.c:(.text+0x130): undefined reference to `__aeabi_uidivmod' Il processore non ha istruzioni per divisione e modulo, il compilatore le sostituisce con invocazioni di funzioni, ma il linker non le trova 1.1.3 Ottimizzare il codice per eseguire solo la divisione, non il modulo: +-------------------------------+ |[...] | |while (v != 0) { | | unsigned long w = v / 10; | | r = v - w * 10; | | v = w; | | buf[--i] = (char)('0'+r); | |} | +-------------------------------+ 1.1.4 Provare a compilare: uart1.o: In function `putu': uart1.c:(.text+0x124): undefined reference to `__aeabi_uidiv' 1.3 Aggiungere al Makefile il supporto per l'emulatore software 1.4 Aggiungere extern per putu() in comm.h: extern void putu(unsigned long); 1.5 Provare la funzione putu() stampando in main() il valore 0xbadc0de 2 Stampare valori decimali con segno 2.1 Scrivere la funzione putd() per stampare valori in decimale con segno +--------------------+ |void putd(long v) | |{ | | if (v < 0) { | | putc('-'); | | v = -v; | | } | | putu(v); | |} | +--------------------+ 2.2 Aggiungere extern per putd() in comm.h: extern void putd(long); 2.3 Provare la funzione putd() stampando in main() il valore -195936478 *** Stampa di numeri in virgola mobile 3 Stampare valori in virgola mobile 3.1 Scrivere la funzione putf() per stampare valori in virgola mobile (double) +-------------------------------+ |void putf(double v, int prec) | |{ | | int i; | | | | if (v < 0.0) { | | putc('-'); | | v = -v; | | } | | putu(v); | | putc('.'); | | for (i=0; i