[RISOLTO] 1 << ( sizeof(num_type) * 8 )

giuscri
Ciao ragazzi! Sto leggendo un programma scritto dal mio professore e ho trovato qualcosa di veramente poco chiaro:

#include <iostream>

#include <ctime> // clock_gettime() nanosleep()
#include <cstdlib> // srand() rand()

class lottery
{
  public:

    typedef unsigned short num_type;

    lottery(unsigned long long i_max_num = (1<<(sizeof(num_type)*8))) // Constructor
     {
      timespec current_time;
      clock_gettime(CLOCK_REALTIME,&current_time); // If it fails we take 
                                                   // random initial value;
// ...


Come devo interpretare quel

1<<(sizeof(num_type)*8))


?

Tra l'altro mi aspetterei che $"lottery(unsigned long long)"$ sia un costruttore con argomenti passati dall'utente. Qualche riga più sotto infatti trovo

lottery::num_type my_guess;
lottery easy_lottery(3);


Ma quel $3$ non so assolutamente come possa essere passato al costruttore dato che

unsigned long long i_max_num = (1<<(sizeof(num_type)*8))


mi sa di un'assegnazione che avviene sempre nello stesso modo -i.e. il $3$ dove lo metto?

Se dovessi essere stato poco chiaro, nello spoiler il programma completo:



Grazie! :)

Risposte
claudio862
In C++ gli argomenti delle funzioni possono avere valori di default.

void f(int a = 3);

...

f(57); // Chiama f() con argomento 57

f(); // Chiama f() con argomento (di default) 3.


Il costruttore è una funzione come le altre (più o meno), quindi "(1<<(sizeof(num_type)*8))" è il valore di default dell'argomento.

L'operatore << sposta i bit dell'argomento a sinistra di n posizioni, dove n è l'argomento a destra. Quindi sposta i bit di 1 (che sono 000...00001) di sizeof(num_type)*8 posizioni a sinistra.

In sostanza, se num_type è grande 16 byte (128 bit) sposta i bit di 1 di 128 posizioni a sinistra. Quindi il valore finale è 10000...000 con 128 zeri. Che è uno più del massimo valore possibile memorizzabile in un num_type (se è unsigned).

In realtà quell'espressione non è completamente portabile, non è detto che un char sia composto da 8 bit (dovresti usare la macro CHAR_BIT definita (mi pare) in cstdef). Inoltre sarebbe meglio usare la classe numeric_limits, che è decisamente più chiara:

#include <limits>

typedef ... num_type;

unsigned long long a = (1<<(sizeof(num_type)*8))

unsigned long long b = std::numeric_limits<num_type>::max() + 1;

giuscri
"claudio86":
In C++ gli argomenti delle funzioni possono avere valori di default.

void f(int a = 3);

...

f(57); // Chiama f() con argomento 57

f(); // Chiama f() con argomento (di default) 3.


Il costruttore è una funzione come le altre (più o meno), quindi "(1<<(sizeof(num_type)*8))" è il valore di default dell'argomento.

L'operatore << sposta i bit dell'argomento a sinistra di n posizioni, dove n è l'argomento a destra. Quindi sposta i bit di 1 (che sono 000...00001) di sizeof(num_type)*8 posizioni a sinistra.

In sostanza, se num_type è grande 16 byte (128 bit) sposta i bit di 1 di 128 posizioni a sinistra. Quindi il valore finale è 10000...000 con 128 zeri. Che è uno più del massimo valore possibile memorizzabile in un num_type (se è unsigned).


Grande!

"claudio86":
In realtà quell'espressione non è completamente portabile, non è detto che un char sia composto da 8 bit (dovresti usare la macro CHAR_BIT definita (mi pare) in cstdef). Inoltre sarebbe meglio usare la classe numeric_limits, che è decisamente più chiara:

#include <limits>

typedef ... num_type;

unsigned long long a = (1<<(sizeof(num_type)*8))

unsigned long long b = std::numeric_limits<num_type>::max() + 1;


Ok, questo cercherò di ricordarmelo.

Grazie mille! Buona giornata! :)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.