[Risolto] Compilazione programmabile

Ciao gente,
Trovo comodo fare dei #define per alcuni parametri dentro il programma. In tal modo le modifiche si concentrano in un solo punto.
Ora volevo fare un calcolo che mi desse un valore binario in proporzione ad un numero.
Esempio:

#define MYVAL 4
#define MASK b'00001111' // da farsi in proporzione a MYVAL
// se invece lo cambio dovrebbe calcolare diverso
#define MYVAL 6
#define MASK b'00111111' // da farsi in proporzione a MYVAL

Quindi la domanda: "esiste un modo per calcolare tramite il preprocessore quanti shift left far fare ?"

#define MASK ((1 << MYVAL) - 1)

Dovrebbe funzionare.

Capisco il left shift, ma il meno uno è per impostare il carry oppure è per shiftare il valore negativo (che sono tutti 1) ?

Perfetto ! Karmato per Natale :smiley:

Se shifti verso sinistra 1 tot volte, p.e. 6, ottieni “00100000”, sottraendo 1, il -1, ottieni “00011111”, pertanto non è il risultato atteso, devi modificare la #define in questo modo:

#define MASK ((1 << (MYVAL+1)) - 1)

Attenzione che con questo sistema è impossibile ottenere “11111111” su variabili a 8 bit, dovresti fare prima una verifica e se MYVAL è 8 semplicemente sottrai 1 a MASK, così diventa “11111111”, ovvero -1 riferito ad un valore signed.

Mi sa che stavolta hai fatto male i conti, @astrobeed ;).

Dovrebbe inoltre funzionare anche con 8, anzi, fino a 16, e pure con 0, ma effettivamente è meglio fare qualche test ed eventualmente aggiungere un cast a byte al risultato finale.

Beh, tengo conto del problema. Infatti ho avuto lo stesso pensiero di come agisse su diverso tipo di cast.
Intanto lo uso su una PORT e rimango nell' ordine del byte.

SukkoPera:
Mi sa che stavolta hai fatto male i conti, @astrobeed ;).

Hai ragione, sono partito dal presupposto che MASK vale 0, ma in realtà si parte da 1 shiftato per sei volte quindi il valore ottenuto è "01000000", rimane sempre la questione degli otto 1 che su un byte porta al overflow e il valore rimane 0, però si può usare un int come variabile di appoggio per poi farne il cast a byte.

In realtà, shiftando di più di 8 posizioni si ottengono sì tutti 0, ma il -1 li fa poi diventare tutti 1, per cui dovrebbe funzionare comunque.

Shiftando di 0 posizioni si ottiene 1, che il -1 riconduce a 0, correttamente.

In realtà poi, come ho accennato sopra, il primo “1”, l’operando sottoposto a shift insomma, secondo lo standard viene interpretato come int, quindi nel nostro caso a 16 bit, per cui la soluzione proposta dovrebbe dare il risultato atteso per MYVAL compreso tra 0 e 16, estremi inclusi. Per avere valori corretti oltre tale range, occorre castare l’1 a long (1L). Questo almeno sulla carta, se interpreto correttamente lo standard :).