In matematica, la base di un sistema di numerazione posizionale è il numero di cifre distinte, inclusa quella per lo 0, che il sistema usa per rappresentare i numeri. La rappresentazione in base 10 è l'ordinaria scrittura dei numeri a cui siamo abituati.
Definizione
[modifica | modifica wikitesto]Un numero naturale n viene rappresentato in base b associando una sequenza finita di numeri naturali ciascuno scelto tra 0 e b-1 in modo tale che valga l'uguaglianza:
Si può dimostrare che questa associazione definisce una corrispondenza biunivoca tra l'insieme dei numeri naturali e l'insieme delle sequenza finite composte da numeri scelti tra 0 e b-1.
Per segnalare che un numero è rappresentato in una certa base, la si può indicare al suo pedice, ad esempio: 1101012=5310. Visto che in una base b, il numero b è sempre scritto come 10 (dato che b=1·b1+0·b0), nella rappresentazione della base numerica potrebbe essere consigliabile l'uso di "9+1" o "A" al posto di un autoreferenziale "10", il cui contenuto, visto il contesto, potrebbe risultare non univoco e quindi paradossale.
In una data base b, i numeri razionali rappresentabili con un numero finito di cifre dopo la virgola sono tutti e soli quelli che, espressi sotto forma di frazione irriducibile m/n, non hanno fattori primi di n che non siano anche fattori primi di b. Ad esempio, i fattori primi di 10 sono 2 e 5, per cui le frazioni che generano numeri periodici in base 10 sono quelle che (ridotte in forma normale) al denominatore hanno fattori primi diversi da 2 e da 5. I numeri irrazionali non sono esprimibili con un numero finito di cifre in nessuna base.
Simboli di cifra
[modifica | modifica wikitesto]Per basi minori o uguali a 10, generalmente si usano le comuni cifre 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9.
Per basi maggiori di 10, è necessario introdurre altri simboli, di solito lettere. Nel sistema esadecimale sono usate le cifre 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E ed F. Così, ad esempio, F3A0 in base 16 equivale a 62368 in base 10. Un sistema di numerazione di base 2B o 2B+1 può anche usare B cifre, di cui alcune segnate e che valgono come negative, ovvero N, ..., 2, 1, 0, 1, 2, ..., N. In questo caso si parla di sistema bilanciato; si veda ad esempio il sistema ternario bilanciato.
Esempi di conversione di base
[modifica | modifica wikitesto]Da base diversa da 10 alla base 10
[modifica | modifica wikitesto]Per scrivere un numero in base diversa da 10 in un numero in base 10 si deve in primo luogo scriverlo sotto forma polinomiale. Riportiamo un esempio che risulta di più facile comprensione rispetto a una spiegazione astratta del caso generale.
Per trasformare, ad esempio, il numero (1010)2 dalla base 2 alla base 10:
- scriviamo il numero sotto forma polinomiale: 1×23+0×22+1×2+0×20;
- eseguiamo le operazioni indicate: 8+2+0;
- otteniamo 10 in base 10. quindi (1010)2=(10)10.
Dalla base 10 a una base diversa da 10
[modifica | modifica wikitesto]Per trasformare un numero in base 10 nella corrispondente scrittura in una base diversa da 10 operiamo con divisioni successive e in particolare dobbiamo tenere in considerazione di quozienti (q) e resti (r) di ogni divisione. Anche in questo caso riportiamo un esempio.
Vogliamo trasformare il numero 428, appartenente al sistema decimale, nel numero corrispondente nella base 6:
- dividiamo 428 per 6: otteniamo q=71, r=2;
- dividiamo il quoziente 71 per 6: otteniamo q1=11, r1=5;
- dividiamo il quoziente 11 per 6: otteniamo q2=1, r2=5;
- dividiamo il quoziente 1 per 6: otteniamo q3=0, r3=1.
Il procedimento è terminato, perché q=0. Scrivendo i resti ottenuti a partire dall'ultimo fino al primo otteniamo il numero (1552)6 che è il numero cercato.
Implementazione dell'algoritmo
[modifica | modifica wikitesto]Segue un'implementazione dell'algoritmo per la conversione di base di un numero.
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define MAX_LENGTH 32
#define MAX_BASE 36
#define MIN_BASE 2
#define BUFFER_SIZE 100
// Converte un carattere nel suo valore intero in base al sistema numerico
int char_to_value(char c) {
if (isdigit(c)) {
return c - '0';
} else if (isalpha(c)) {
return toupper(c) - 'A' + 10;
}
return -1;
}
// Converte un valore intero nella sua rappresentazione in caratteri nel sistema numerico
char value_to_char(int value) {
if (value < 0 || value >= MAX_BASE) {
return '\0';
}
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
}
// Convalida che tutti i caratteri nell'input siano validi per la base specificata
bool validate_input(const char* input, int base) {
if (!input || !*input) { // Controlla se la stringa è NULL o vuota
return false;
}
for (int i = 0; input[i] != '\0'; i++) {
if (!isalnum(input[i])) { // Controlla i caratteri non alfanumerici
return false;
}
int value = char_to_value(input[i]);
if (value == -1 || value >= base) {
return false;
}
}
return true;
}
// Converte una stringa numerica da una base all'altra, memorizzando il risultato in to_value
bool tobase(const char *from_value, char *to_value, int from_base, int to_base) {
// Validazione dei parametri
if (!from_value || !to_value ||
from_base < MIN_BASE || from_base > MAX_BASE ||
to_base < MIN_BASE || to_base > MAX_BASE) {
return false;
}
size_t input_len = strlen(from_value);
if (input_len == 0 || input_len > MAX_LENGTH) {
return false;
}
if (!validate_input(from_value, from_base)) {
return false;
}
// Convertire il numero di input in from_base in intero
unsigned long long int_value = 0;
for (size_t i = 0; from_value[i] != '\0'; i++) {
int digit_value = char_to_value(from_value[i]);
// Controllare l'overflow prima della moltiplicazione
if (int_value > ULLONG_MAX / from_base) {
return false;
}
int_value *= from_base;
// Controllare l'overflow prima dell'aggiunta
if (int_value > ULLONG_MAX - digit_value) {
return false;
}
int_value += digit_value;
}
// Gestisci direttamente lo zero
if (int_value == 0) {
to_value[0] = '0';
to_value[1] = '\0';
return true;
}
// Convertire il valore intero in to_base
char result[MAX_LENGTH];
int pos = 0;
while (int_value > 0 && pos < MAX_LENGTH - 1) {
int remainder = int_value % to_base;
result[pos++] = value_to_char(remainder);
int_value /= to_base;
}
if (int_value > 0) {
return false; // Caso di overflow se il risultato è troppo grande per il buffer
}
// Invertire il risultato per ottenere l'ordine corretto
for (int i = 0; i < pos; i++) {
to_value[i] = result[pos - 1 - i];
}
to_value[pos] = '\0';
return true;
}
int main() {
char input[BUFFER_SIZE];
char output[MAX_LENGTH];
int from_base, to_base;
char line[BUFFER_SIZE];
printf("Inserisci il numero da convertire: ");
if (!fgets(line, sizeof(line), stdin)) {
printf("Errore di lettura!\n");
return 1;
}
// Rimuovi la nuova riga e controlla la lunghezza dell'input
size_t len = strlen(line);
if (len > 0 && line[len-1] == '\n') {
line[len-1] = '\0';
len--;
}
if (len >= MAX_LENGTH) {
printf("Input troppo lungo! Massimo %d caratteri.\n", MAX_LENGTH - 1);
return 1;
}
strncpy(input, line, MAX_LENGTH - 1);
input[MAX_LENGTH - 1] = '\0';
printf("Inserisci la base di origine (%d-%d): ", MIN_BASE, MAX_BASE);
if (scanf("%d", &from_base) != 1) {
printf("Input non valido per la base di origine!\n");
return 1;
}
printf("Inserisci la base di destinazione (%d-%d): ", MIN_BASE, MAX_BASE);
if (scanf("%d", &to_base) != 1) {
printf("Input non valido per la base di destinazione!\n");
return 1;
}
if (tobase(input, output, from_base, to_base)) {
printf("Risultato: %s\n", output);
return 0;
} else {
printf("Errore di conversione!\n");
return 1;
}
}
Generalizzazioni del concetto di base
[modifica | modifica wikitesto]Le basi comunemente usate sono tutte numeri naturali, ma si possono costruire anche sistemi di numerazione basati su basi negative, non intere (come la base aurea) e complesse.
Voci correlate
[modifica | modifica wikitesto]Collegamenti esterni
[modifica | modifica wikitesto]- (EN) Eric W. Weisstein, Base, su MathWorld, Wolfram Research.
- Convertitore tra basi, su tinytools.nu. URL consultato il 17 aprile 2012 (archiviato dall'url originale il 26 aprile 2012).