![]()
Sistemi di Numerazione a Base fissa
Sistema Binario Proposta di Lavoro N°1
Proposta di Lavoro N°2 (programma
di conversione di un numero binario in decimale e viceversa)
![]()
Sistemi di numerazione a base fissa
Un sistema di numerazione è un insieme di regole e simboli il cui utilizzo permette di rappresentare delle quantità.
Per definire un sistema a base fissa si può affermare che deve essere composto da:
un numero maggiore di uno che costituisce la base e che indicheremo con B;
un insieme di simboli che rappresentano i numeri a partire da zero fino al numero precedente la base (B simboli in tutto);
ogni numero è rappresentato con una sequenza di simboli in modo posizionale, in altre parole le cifre, secondo la posizione nel numero, assumono un valore ben preciso e diverso da quello delle cifre precedenti o successive (punto radice = punto decimale).
| Ordine di grandezza | Ak | ... | A2 | A1 | A0 | · | A-1 | A-2 | ... | A-n |
| Posizione | k | ... | 2 | 1 | 0 | · | -1 | -2 | ... | -n |
| Valore posizionale | Bk | ... | B2 | B1 | B0 | · | B-1 | B-2 | ... | B-n |
Tutti i sistemi di numerazione posizionale a base fissa, indipendentemente dalla base prescelta per la rappresentazione, soddisfano alle seguenti caratteristiche:
sono sistemi non ridondanti, non vi sono quindi sequenze di simboli che non rappresentano alcun numero;
sono a rango illimitato, in altre parole ogni numero può essere rappresentato, non importa quanto grande o piccolo sia;
sono a rappresentazione unica, in altre parole ogni numero ha una sola rappresentazione, costituita da un insieme ordinato di cifre.
Base: numero di simboli del sistema í 0, 1, 2, 3, 4, 5, 6, 7, 8, 9ý
Rappresentazione polinomiale:
grado (N - 1), dove N è il numero di cifre della parte intera.
838.34= 8*102+3*101+8*100+3*10-1+4*10-2 = 800+30+8+0.3+0.04
Base: numero di simboli del sistema í 0, 1ý
Corrispondenza con gli stati dei dispositivi elettronici che possono assumere solo due livelli: basso (0), alto (1). È importante mettere in evidenza che non contano i valori assoluti dei livelli, ma conta soprattutto questa duplice possibilità che può essere associata ai seguenti pensieri logici: vero o falso, spento o acceso, ON e OFF.
Maggior numero di cifre per rappresentare lo stesso numero in un altro sistema.
LSB (Least Significant Bit), bit meno significativo.
MSB (Most Significant Bit), bit più significativo.
ADDIZIONE: le regole della somma danno i seguenti risultati.
| 0 + 0 = 0 | ||
| 0 + 1 = 1 | ||
| 1 + 0 = 1 | ||
| 1 + 1 = 0 | CARRY = 1 |
Un esempio chiarirà meglio il modo di esecuzione di una somma aritmetica.
| 1 | 1 | 1 | 1 | ||||
| 1 | 1 | 0 | 1 | 0 | 0 | + | |
| 1 | 1 | 1 | 0 | 1 | |||
| ------------------------------------------ | |||||||
| 1 | 0 | 1 | 0 | 0 | 0 | 1 | |
DIRETTA: le regole della sottrazione diretta danno i seguenti risultati.
| 0 - 0 = 0 | ||
| 1 - 0 = 1 | ||
| 1 - 1 = 0 | ||
| 0 - 1 = 1 | BORROW = 1 |
Un esempio chiarirà meglio il modo di esecuzione di una sottrazione diretta.
| 0 | 0 | 1 | ||||||||||
| 1 | 0 | 1 | 0 | 0 | 1 | - | ||||||
| 1 | 0 | 1 | 1 | 0 | ||||||||
| ------------------------------------- | ||||||||||||
| 1 | 0 | 0 | 1 | 1 | ||||||||
Se eseguendo una sottrazione diretta dobbiamo, per qualche bit, prendere il borrow dalle cifre che lo precedono, bisogna distinguere due casi:
la cifra immediatamente precedente è uno nel qual caso è sufficiente ricordare che la cifra da cui si prende il borrow, si riduce a zero e la cifra successiva aumenta di due (10 in binario);
la cifra (od alcune cifre) immediatamente precedente è zero, nel qual caso il borrow si prende dalla prima cifra non nulla, tutti gli zeri diventano uno ed infine il bit su cui si sta operando è aumentato di due (10 in binario).
COMPLEMENTO
1. CB [N] = BK - N C10 [24] = 102 - 24 = 76 C2 [100101] = 26 - 100101 = 011011
2.
| 1 | 1 | 1 | 1 | 1 | 2 | |||
| C2 [ | 1 | 0 | 0 | 1 | 0 | 1 ] = 011011 | ||
| 1 | 1 | 1 | 1 | 1 | 2 | |||
| C2 [ | 1 | 0 | 0 | 0 | 1 | 0 ] = 011110 | CARRY! |
3.
| 100101 ® | 011010 + | complemento a 1 | |
| 1 = | |||
| ------------ | |||
| 011011 | complemento a 2 |
4. Dato un numero N, per ottenere il suo complemento a due, si riscrivono i bit del numero stesso a partire da LSB lasciando inalterati tutti gli zeri fino a quando s'incontra il primo uno lo si ricopia e s'invertono i bit successivi (gli zeri in uno, gli uno in zero).
Per esempio, 100101 ® 011011.
| Proposta di lavoro N°1 |
Costruire uno spread sheet che consenta di acquisire un valore intero decimale negativo e di fornirne il complemento a due, utilizzando la regola numero tre.
| A B | C |
D | E | F | G | H | I | J | K | |
| 1 | VALORE INTERO | -16 |
||||||||
| 2 | ||||||||||
| 3 | Valore assoluto | 16 |
||||||||
| 4 | ||||||||||
| 5 | Posto | 7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
| 6 | ||||||||||
| 7 | Configurazione binaria | 0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
|
| 8 | ||||||||||
| 9 | Complemento a uno | 1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
|
| 10 | ||||||||||
| 11 | Riporto | 0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
|
| 12 | ||||||||||
| 13 | Complemento a due | 1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
Per il calcolo del valore assoluto relativo a C3 si potrà utilizzare la formula:
=ASS(C1)
Per il calcolo delle cifre binarie relative a C3, in ogni cella della riga 7 (ad esempio K7) si potrà utilizzare la formula:
=RESTO(INT($C$3/(POTENZA(2,K5)));2)
Per il calcolo del complemento a uno, si può ricorrere alla funzione di selezione:
=SE(K7=0;1;0)
Per il calcolo del complemento a due occorre poi sommare uno alla stringa trasformata, ciò può essere fatto riportando uno in K11 e poi facendo calcolare al PC la somma nella riga 13. In quest' operazione, dato che occorre tenere conto degli eventuali riporti, dalla colonna J fino alla colonna C della riga 11 saranno calcolati i riporti tramite la formula che, riferita alla colonna J assume la forma:
=INT((K9+K11)/2)
In modo analogo la formula per la riga 15 è:
=RESTO((K9+K11);2)
RISALIRE DAL COMPLEMENTO AL NUMERO
3.
| 011011 - | ||
| 1 = | ||
| ------------ | ||
| 011010 | si sottrae 1 | |
| 100101 | complemento a 1 |
4. 011011 ® 100101
La sottrazione di due numeri di k cifre può essere sostituita dalladdizione del minuendo al complemento del sottraendo (le cifre devono essere pareggiate a quelle del minuendo) purché nel risultato si trascuri il carry in posizione (k + 1).
Si noti che il metodo esposto è quello che in pratica è usato nei computer e leliminazione della cifra più significativa è eseguita in modo automatico dai circuiti elettronici.
DIVISIONE: è una sequenza di sottrazioni successive.
MOLTIPLICAZIONE: si riduce ad una serie di somme successive.
CONVERSIONE BINARIO-DECIMALE
Si rappresenta il numero binario in forma polinomiale e si sommano i valori decimali dei singoli termini del polinomio.
(10101.1011)2 = (21.6875)10
1*24 +0*23 +1*22 +0*21 +1*20 +1*2-1 +0*2-2 +1*2-3 +1*2-4 =16+4+1+0.5+0.125+0.0625
CONVERSIONE DECIMALE-BINARIO
Nel caso di numero intero si utilizza il metodo delle divisioni successive per la base B del sistema, il resto della divisione costituisce la cifra binaria, si procede così sul quoziente fino a quando questultimo si annulla. Se il numero è frazionario si utilizza il metodo delle moltiplicazioni successive per la base B del sistema, la parte intera (zero o uno) rappresenta la cifra binaria, si procede così fino allannullamento della parte frazionaria o fino a quando la precisione della conversione risulta sufficiente.
(316.5625)10 = (100111100.1001)2
| 316:2=158 | 0 | | 0.5625*2=1.125 | 1 | ½ |
| 158:2=79 | 0 | ½ | 0.125*2=0.25 | 0 | ½ |
| 79:2=39 | 1 | ½ | 0.25*2=0.5 | 0 | ½ |
| 39:2=19 | 1 | ½ | 0.5*2=1.0 | 1 | ¯ |
| 19:2=9 | 1 | ½ | |||
| 9:2=4 | 1 | ½ | |||
| 4.2=2 | 0 | ½ | |||
| 2:2=1 | 0 | ½ | |||
| 1:2=0 | 1 | ½ |
Base: numero di simboli del sistema í 0, 1, 2, 3, 4, 5, 6, 7ý
è corretto leggere il numero ottale (574)8 come numero: cinque-sette-quattro e non cinquecentosettantaquattro poiché questultima è una dicitura che caratterizza solo il sistema decimale.
ADDIZIONE
| 1 | 1 | 1 | |||||
| 4 | 2 | 1 | 6 + | ||||
| 5 | 7 | 4 | |||||
| --------------------- | |||||||
| 5 | 0 | 1 | 2 | ||||
SOTTRAZIONE
| 5 | 4 | 1 | 1 | 1 | |||||||||
| 5 | 6 | 0 | 5 | 2 - | 5 | 6 | 0 | 5 | 2 + | ||||
| 4 | 2 | 4 | 5 | 7 | 3 | 5 | 3 | 3 | |||||
| ----------------------------- ----------------------------- | |||||||||||||
| 5 | 1 | 6 | 0 | 5 | 5 | 1 | 6 | 0 | 5 | ||||
CONVERSIONE OTTALE-DECIMALE
(24.12)8 = (20.15625)10
2*81+4*80+1*8-1+2*8-2 = 16+4+0.125+0.03125
CONVERSIONE DECIMALE-OTTALE
(4303.5625)10 = (10317.44)8
| 4303:8=537 | 7 | | 0.5625*8=4.5 | 4 | ½ |
| 537:8=67 | 1 | ½ | 0.5*8=4.0 | 4 | ¯ |
| 67:8=8 | 3 | ½ | |||
| 8:8=1 | 0 | ½ | |||
| 1:8=0 | 1 | ½ |
CONVERSIONE BINARIO-OTTALE E VICEVERSA
Si suddivide il numero binario in gruppi di tre bit a partire dal punto binario, si completano con zero i gruppi estremi con meno di tre bit e si associa a ciascun gruppo il corrispondente ottale.
(1010.1101)2 = (12.64)8 ® (001) (010) · (110) (100)
| DECIMALE | OTTALE | BINARIO |
| 0 | 0 | 000 |
| 1 | 1 | 001 |
| 2 | 2 | 010 |
| 3 | 3 | 011 |
| 4 | 4 | 100 |
| 5 | 5 | 101 |
| 6 | 6 | 110 |
| 7 | 7 | 111 |
Base: numero di simboli del sistema
í 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A (10), B (11), C (12), D (13), E (14), F (15)ý .
La CPU (Central Processing Unit) lavora con parole (word) binarie formate da un numero di bit multiplo del due, è facile rappresentarle in esadecimale.
| BIT | NOME | CIFRE ESADECIMALI |
| 4 | nibble | 1 |
| 8 | byte | 2 |
| 16 | word | 4 |
| 32 | doubleword | 8 |
| 64 | quadword | 16 |
ADDIZIONE
| 1 | ||||||||||
| E | 0 | 1 | A | C + | ||||||
| F | 4 | 2 | ||||||||
| ------------------------- | ||||||||||
| E | 1 | 0 | E | E | ||||||
SOTTRAZIONE
| 1 | 5 | 1 | 1 | 1 | ||||||||||||||||||||
| C | 2 | A | 6 | 1 - | C | 2 | A | 6 | 1 + | |||||||||||||||
| B | 0 | E | F | F | 4 | F | 2 | |||||||||||||||||
| -------------------------- ----------------------------- | ||||||||||||||||||||||||
| C | 1 | F | 5 | 3 | C | 1 | F | 5 | 3 | |||||||||||||||
CONVERSIONE BINARIO-ESADECIMALE E VICEVERSA
Si suddivide il numero binario in gruppi di quattro bit a partire dal punto binario, si completano con zero i gruppi estremi con meno di quattro bit e si associa a ciascun gruppo il corrispondente esadecimale.
(1000101011101.1010)2 = (115D.A)H ® (0001) (0001) (0101) (1101) · (1010)
CONVERSIONE OTTALE-ESADECIMALE E VICEVERSA
Il metodo più veloce per passare dal sistema ottale allesadecimale (o viceversa) è quello di passare attraverso il sistema binario.
(352)8 = (EA)H ® (352)8 = (11101010)2 = (EA)H
| DECIMALE | ESADECIMALE | BINARIO |
| 0 | 0 | 0000 |
| 1 | 1 | 0001 |
| 2 | 2 | 0010 |
| 3 | 3 | 0011 |
| 4 | 4 | 0100 |
| 5 | 5 | 0101 |
| 6 | 6 | 0110 |
| 7 | 7 | 0111 |
| 8 | 8 | 1000 |
| 9 | 9 | 1001 |
| 10 | A | 1010 |
| 11 | B | 1011 |
| 12 | C | 1100 |
| 13 | D | 1101 |
| 14 | E | 1110 |
| 15 | F | 1111 |
CONVERSIONE ESADECIMALE-DECIMALE
(8BA.3)H = (2234.18)10
8*162+B*161+A*160+3*16-1 = 2048+176+10+0.18
CONVERSIONE DECIMALE-ESADECIMALE
(8826.62)10 = (227A.9E)H
| 8826:16=551 | 10 | | 0.62*16=9.92 | 9 | ½ |
| 551:16=34 | 7 | ½ | 0.92*16=14.72 | 14 | ¯ |
| 34:16=2 | 2 | ½ | 0.72*16=... | ||
| 2:16=0 | 2 | ½ |
Un modo più semplice e rapido per eseguire queste conversioni è quello di utilizzare un'opportuna tabella, per valori da (0)10 a (1048575)10; da (00000)H a (FFFFF)H.
Per convertire da esadecimale a decimale
Le colonne corrispondono al numero di cifre del valore esadecimale, le righe ai valori delle singole cifre esadecimali. Il valore (E)H ha una cifra ed il suo valore decimale è (colonna DIG. 1, riga E = 14). Il valore (E7)H ha due cifre ed il suo valore decimale è (colonna DIG. 2, riga E) + (colonna DIG. 1, riga 7) = (231)10. Il valore (E742)H ha quattro cifre ed il suo valore decimale è (colonna DIG. 4, riga E) + (colonna DIG. 3, riga 7) + (colonna DIG. 2, riga 4) + (colonna DIG. 1, riga 2) = (59202)10.
Per convertire da decimale ad esadecimale
Si trova il più vicino numero nella tabella, uguale o minore al numero decimale. La prima cifra del valore esadecimale è il numero nel lato sinistro della corrispondente riga (nella colonna ESAD). Si sottrae il valore della tabella dal numero originale e, si ripete il processo fino a quando il numero decimale è pari a zero.
Trovare il valore esadecimale di (1012342)10
Decimale Tabella Esadecimale
1012342 983040 = F
29302 28672 = 7
630 512 = 2
118 112 = 7
6 6 = 6
Pertanto (1012342)10 = (F7276)H
| ESAD | DIG. 5 | DIG. 4 | DIG. 3 | DIG. 2 | DIG. 1 | BINARIO |
| 0 | 0 | 0 | 0 | 0 | 0 | 0000 |
| 1 | 65536 | 4096 | 256 | 16 | 1 | 0001 |
| 2 | 131072 | 8192 | 512 | 32 | 2 | 0010 |
| 3 | 196608 | 12288 | 768 | 48 | 3 | 0011 |
| 4 | 262144 | 16384 | 1024 | 64 | 4 | 0100 |
| 5 | 327680 | 20480 | 1280 | 80 | 5 | 0101 |
| 6 | 393216 | 24576 | 1536 | 96 | 6 | 0110 |
| 7 | 458752 | 28672 | 1792 | 112 | 7 | 0111 |
| 8 | 524288 | 32768 | 2048 | 128 | 8 | 1000 |
| 9 | 589824 | 36864 | 2304 | 144 | 9 | 1001 |
| A | 655360 | 40960 | 2560 | 160 | 10 | 1010 |
| B | 720896 | 45056 | 2816 | 176 | 11 | 1011 |
| C | 786432 | 49152 | 3072 | 192 | 12 | 1100 |
| D | 851968 | 53248 | 3328 | 208 | 13 | 1101 |
| E | 917504 | 57344 | 3584 | 224 | 14 | 1110 |
| F | 983040 | 61440 | 3840 | 240 | 15 | 1111 |
| Proposta di lavoro N°2 |
Realizzare un programma che, dato un numero binario in input, lo converta nel corrispondente numero decimale e viceversa.
/* Conversione da binario a decimale
bin è la sequenza dei bit del numero binario, i è il contatore di posizione nella sequenza bin
l è la lunghezza della sequenza bin, s è il valore di posizione dei bit nel numero
d è il valore del numero binario in decimale
i=0
if bin[i]!=0 then d=1
s=1
for i=1 to l
begin
s=s*2; if bin[i]!=0 then d=d+s
end
scrivi: Il numero in decimale è d. */
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <conio.h>
int main(void)
{ int bin[30];int i,l,d,s;char buff[20];
do { i=0; l=0; d=0;clrscr();
printf("\nPer terminare l'inserimento dei bit digitare il <.>\n\n");
do { printf ("Dammi il bit %d del numero in binario partendo dall'LSB: ",i); bin[i] = atoi (gets(buff));
if (strcmp(buff,"."));i++;
} while(strcmp(buff,"."));
l=i;i=0; if (bin[i]!=0) d=1;i++;s=1;
for(i=1;i<l;i++) { s*=2; if(bin[i]!=0) d+=s; }
printf ("\nIl numero in decimale è: %d",d); gotoxy(1,23);
puts("PREMERE ESC PER TERMINARE, UN TASTO QUALSIASI PER CONTINUARE ");
} while ( getch() !=0x1B);return (0);
}
/* Conversione da decimale a binario
n è il numero in decimale, bit è la sequenza dei bit ottenuti dalle divisioni successive di n
i è il contatore della sequenza bit
leggi n
i=1
while n>0
begin
if n%2 then bit[i]=1 else bit[i]=0; n=n/2; i=i+1
end
scrivi: Il numero in binario è bit. */
#include<stdio.h>
#include <conio.h>
int main(void)
{ int bit[30];int i,n;
do { i=0; n=0;clrscr();
printf ("\nDammi il numero in decimale: ");scanf ("%d",&n);
while(n>0) { if(n%2) bit[i]=1; else bit[i]=0; n /=2;i++; }
printf ("\nIl numero in binario è: "); while(i>0) { i--;printf ("%d",bit[i]); } gotoxy(1,23);
puts("PREMERE ESC PER TERMINARE, UN TASTO QUALSIASI PER CONTINUARE ");
} while ( getch() !=0x1B);return (0);
}
#include <stdio.h>
#include <conio.h>
void convnum (int number, char *buffer,int base, char *names[]);
int test[] = {1,3,7,15,31,63,127,255,511,0};
char *decsys[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"},
*octsys[] = {"0", "1", "2", "3", "4", "5", "6", "7"},
*binsys[] = {"0", "1"},
*hexsys[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
int main (void)
{ int i;char buffer[25];clrscr(); printf ("\n\nDECIMALE:\n");i = 0;
do { convnum (test[i], buffer, 10, decsys);printf(" %s",buffer); } while (test[i++]);
printf("\n\nOTTALE:\n");i = 0;
do { convnum (test[i], buffer, 8, octsys);printf(" %s",buffer); } while (test[i++]);
printf("\n\nBINARIO:\n");i = 0;
do { convnum (test[i], buffer, 2, binsys);printf(" %s",buffer); } while (test[i++]);
printf("\n\nESADECIMALE:\n");i = 0;
do { convnum (test[i], buffer, 16, hexsys);printf(" %s",buffer); } while (test[i++]);getch();return (0);
}
void convnum (int number, char *buffer,int base, char *names[])
{ int basenum,nextpower,digit;char *c;
if (number < 0) { number = -number;*buffer++ = '-';} basenum = 1;
while ((nextpower = basenum * base) <= number) basenum = nextpower;
for (;basenum; basenum /= base)
{ digit = number / basenum;number -= digit * basenum; for (c = names [digit]; *c; c++) *buffer++ = *c;
} *buffer = '\0';
}
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <conio.h>
void StampaInBase (int base, long num, char *s), InputStringa (char *prompt, char *s);
int InputNumero (long *np);
enum { PREF2 = '%', PREF8 = '@', PREF16 = '$' }; enum { SUFF2 = 'b', SUFF8 = 'q', SUFF16 = 'h' };
const long maxnum = LONG_MAX/16-16; char digit[] = "0123456789abcdef";
/*LONG_MAX è una costante definita in <limits.h> che indica il massimo valore ammissibile per un long. Considerando la tecnica usata nella InputInt per la conversione in un valore numerico della stringa introdotta, maxnum è il massimo valore che, nel peggiore dei casi, non potrà dare overflow durante i calcoli. */
int main(void)
{ long n;
do { clrscr(); puts("\n **** CONVERSIONE DI BASE NUMERICA ****\n\n"
"I numeri possono essere dati in uno dei seguenti formati:\n\n"
" Decimale: nessun prefisso n suffisso (es. 198)\n"
" Binario: prefisso % o suffisso b (es. %110, 110b)\n"
" Ottale : prefisso @ o suffisso q (es. @306, 306q)\n"
" Esadecimale: prefisso $ o suffisso h (es. $c6, c6h)");
InputNumero(&n);printf("\n ");StampaInBase(2,n,"(bin) = ");
StampaInBase(8,n,"(oct) = ");StampaInBase(10,n,"(dec) = "); StampaInBase(16,n,"(hex)\n");
} while (getch() !=0x1b); return (0);
}
/*InputNumero: accetta un numero in binario, ottale, decimale o esadecimale, mette il numero introdotto in *np, ritorna falso (0) se solo return.*/
int InputNumero(long *np)
{ char s[128];int ok,base,d,pref,suff;char *pi,*pf,*p;long pnum;
do { InputStringa("\nNumero positivo da convertire (ESC per smettere): ",s); if (*s == 0) { return(0); }
base = 10;pi = s;pf = s+strlen(s)-1;pref = tolower(*pi); if (pref == PREF2) base = 2;
else if (pref == PREF8) base = 8;else if (pref == PREF16) base = 16; if (base != 10) { pi++;}
else { suff = tolower(*pf); if (suff == SUFF2) base = 2; else if (suff == SUFF8) base = 8;
else if (suff == SUFF16) base = 16;if (base != 10) {pf--;} }
*np = 0; ok = 1;
while (ok && pi <= pf) { p = strchr(digit,tolower(*pi));
if (p == NULL || (d = p-digit) >= base) {
printf("\n- '%c' non è un digit valido in base %d.\n\n\a",*pi,base);ok = 0; }
else { if (*np >= maxnum) { puts("\n- Il numero è troppo grande per essere convertito.\a"); ok = 0;}
else { *np = (*np)*base+d;} } pi++; }
} while (!ok); return (1);
}
/*Dato che pi punta al primo carattere della stringa, esaminiamo se questo è un prefisso che indica una certa base. Bisogna controllare prima i prefissi dei suffissi, altrimenti un numero come $101b potrebbe essere considerato 101 binario (suffisso b) invece che 101b esadecimale (prefisso $). Solo se non ci sono prefissi, si può vedere se c'è un eventuale suffisso. In ogni caso, tolower converte in lettere minuscole (i numeri non cambiano) per cercare poi nella stringa globale digit[]. Il risultato finale andrà in *np, quindi operiamo direttamente su *np. Dovendo fare molte operazioni, sarebbe più efficiente definire una variabile provvisoria (es. n) ed assegnarne poi il risultato a *np alla fine dei calcoli. L'operazione di dereferencing, cioè accedere al valore puntato da un pointer (come *np), è infatti di solito molto più lenta di un accesso diretto al contenuto di una normale variabile (come n). */
void StampaInBase(int base, long num, char *s)
{ char buf[80];int i;
if (num == 0) { putchar(0); } else {i = 0; while (num > 0) {buf[i++] = digit[num%base];num /= base;}
while(i) { putchar(buf[--i]); } } printf("%s",s);
}
/*Le cifre non possono essere stampate direttamente perché sono prodotte in ordine inverso. Le accumuliamo quindi in questa stringa, che verrà poi stampata a rovescio; num%base è il valore dell'ultimo digit a destra (ad esempio, nel caso di 235 in base 10, 235%10 vale 5). Questo valore viene usato come indice nella stringa digit[] per trovare il carattere corrispondente, che viene accumulato nella stringa buf[]; num viene aggiornato in modo da togliere il digit appena considerato (ad esempio, 235/10 vale 23). */
void InputStringa(char *prompt, char *s)
{ char buf[128];int ok;char *p;
do { printf(prompt);ok = (gets(buf) != NULL);if (! ok) putchar('\a'); } while (! ok); p = buf;
while (isspace(*p)) p++; while (*p && (! isspace(*p))) { *s++ = *p++; } *s = 0;
}
/*Si potrebbe leggere la stringa usando semplicemente la sscanf con "%s", ma abbiamo preferito mantenere lo spirito 'a basso livello' del programma, trattando anche le stringhe come i numeri. */