Logaritmo base 2 di un numero?

di il
7 risposte

Logaritmo base 2 di un numero?

Ciao a tutti, il mio nome è Alessandro ho 16 anni e sono nel triennio di un Informatico e Telecomunicazioni.. Vorrei sviluppare un programmino semplice in C che mi codifichi un numero da base 10 a base 2..
Come sapete si fa attraverso le divisioni successive, il resto al contrario è il risultato. Avevo intensione di inserirlo in un vettore di n spazi, a seconda del numero da convertire.
Per esempio 17 io so che è 2^4 + 1 quindi avrò bisogno di 5 spazi nel vettore (10001).. Per fare questo calcolo si può usare anche log_2 di n.. Ma come si scrive in C?


scanf .. n
nBit = log_2_n <---- ?

Grazie millee spero di essermi spiegato

7 Risposte

  • Re: Logaritmo base 2 di un numero?

    Potresti scrivere una funzione che esegue questo calcolo, in fondo dovrebbe essere lo stesso ciclo che utilizzerai per caricare il tuo vettore...
  • Re: Logaritmo base 2 di un numero?

    Il logaritmo in base b di x è eguale al logaritmo in base k di x diviso il logaritmo in base k di b

    Quindi, potendo calcolare il logaritmo in base 10 di x, per calcolare il valore del logaritmo in base 2 farai

    log(x)/log(2)
  • Re: Logaritmo base 2 di un numero?

    E' corretto, ma perchè utilizzare valori a virgola mobile quando si può risolvere con un numero limitato di divisioni per 2 (o meglio con degli shift >>)?
    Inoltre, per Ame97: dato che l'intero da rappresentare sarà a 32 (o 64) bit perchè non utilizzare direttamente una stringa di 32+1 (o 64+1) caratteri, senza andare a perdersi in calcoli inutili?
  • Re: Logaritmo base 2 di un numero?

    Sono d'accordo sulla preparazione del vettore per il massimo numero di bit e per il conteggio durante gli shift ...
  • Re: Logaritmo base 2 di un numero?

    Il prof. opta nel pensiero della programmazione lavatrice, quindi poca Ram.. I programmi devono essere leggeri sennó non userei di certo il C. Ci sono talmente tanti linguaggi più semplici! In visual Basic avrei già risolto tutto! Il vantaggio del C é che é leggero
    Comunque quello che volevo chiedere io é la sintassi vera e propria!! Come faccio a dire che la variabile nBit = log-2-(numero) ?
  • Re: Logaritmo base 2 di un numero?

    Ragiona:
    1) il numero in base 10 e' un intero o un numero con la virgola? -> supponiamo che sia un numero intero
    2) ora, supponiamo che lo leggi dalla tastiera (con la "scanf"). Cisono due casi: 2) lo leggi come stringa (quindi una stringa che descrive un numero in base 10) oppure direttamente come numero.
    3) supponiamo che lo leggi come numero (intero!)
    4) ora in memoria hai il numero intero scritto in base 10 sulla console, E RAPPRESENTATO IN BASE 2 in memoria (i computer usano la rappresentazione binaria, come saprai )

    Quindi il tuo bel 17 (in decimale) e' rappresentato come 10001 (in base 2)

    5) ora facciamo un passo in piu': il tuo numero e' memorizzato in una variable di tipo intero.
    In C ci sono diversi tipi di interi, classificabili in base a 2 parametri:

    a) se con o senza segno (keyword 'signed', che e' il default, oppure 'unsigned')
    b) dal numero di bit: char, short, int, long, long long

    Qui' purtroppo il C non e' mai stato chiaro e il numero di bit per i vari tipi di intero dipende dalla piattaforma (8/16/32/64 bit) e dal compilatore. Supponiamo la situazione piu' comune

    char -> 8 bit
    short -> 16 bit
    int -> 32 bit
    long -> 32 bit
    long long -> 64 bit

    NOTA: I nuovi compilatori C/C++ introducono, finalmente, anche i simboli int8_t, int16_t, int32_t, int64_t ed eventualmente in128_t, e le loro controparti 'unsigned'

    Ora, diciamo che il tuo numero sia memorizzato in una varabile di tipo 'int'. Quindi 32 bit.
    Quindi il tuo 17 non e' 10001, ma piu' precisamente:

    00000000 00000000 00000000 00010001

    (ogni blocchetto sono 8 bit)

    6) ed addesso un'altro passo: in C ci sono tutta una serie di operatori 'bit based', cioe' che ti permettono di manipolare i singoli bit di un intero.

    & -> and
    | -> or
    ~ -> not
    >> -> shift a destra
    << -> shift a sinistra
    >>> -> arithmetic shift.

    7) e qui' sta' il bello: che cosa rappresenta uno shift? A seconda della direzione, una moltiplicazione per 2 o una divisione per 2

    a questo punto hai sufficienti informazioni per calcolare il logaritmo in base due di un intero.
    Hai a disposizione almeno 2 approcci, uno facile e un leggermente meno facile (ma solo un'epsilon). Anzi 3

    a) se inizi da SINISTRA, ti basta trovare la PRIMA posizione un cui un bit NON E' 0
    b) se inizi da DESTRA, ti basta trovare l'ULTIMA posizione un cui un bit NON E' zero
    c) (la piu' facile) che cosa succede se fai uno shift a destra di 1 bit del tuo numero?

    00000000 00000000 00000000 00010001

    diventa

    00000000 00000000 00000000 00001000

    (nota che il n di bit NON CAMBIA) ti sei mangiato un bit!
    Ma se ti mangi tutti i bit a 1, che cosa resta? UN numero in cui TUTTI I BIT sono a 0.
    Ma un intero con TUTTI I BIT a 0, che numero e'? E' ZERO!!!!

    Quindi ti basta shiftare il tuo numero di un bit alla volta a destra fino a che non diventa ZERO!

    NOTA: con che operatre? ">> oppure ">>>"?

    Il numero di shift che hai fatto e' il tuo logaritmo in base 2 del tuo numero.

    ATTENZIONE: e se il numero e' negativo? Il logaritmo di un numero negativo ESISTE, e' un numero complesso, ma comunque puoi calcolarlo lo stesso con qualche trasformazione!
  • Re: Logaritmo base 2 di un numero?

    Per Ame97: se ti scrivi tu una funzione log2(), implementata con divisioni successive o meglio con gli shift (come ti ha spiegato benissimo migliorabile), sarai mille volte più performante di una funzione di libreria che utilizza valori in virgola mobile (con la formula che ti ha suggerito oregon).

    Se poi il tuo programma lo devi far girare in una lavatrice potrebbe essere che il microcontrollore non abbia neanche un'unità a virgola mobile e quindi sia ancora più lento! Senza contare che le funzioni di allocazione potrebbero essere lente (se non addirittura assenti) per cui ti conviene definire un buffer di grandezza sufficiente, a priori.

    Infine, non dipende dal linguaggio: con il VB6 il discorso non cambia, se ti scrivi la tua funzione log2() come ti è stato suggerito sarai velocissimo.
Devi accedere o registrarti per scrivere nel forum
7 risposte