2013-02-01 2 views
5

Ho un incarico che chiede di fare una serie di funzioni solo con questi operatori:efficiente fare un int che ha un 1 ogni 1s, ma uno che è 0 soggiorno 0

! ~ &^| +

In alcuni dei problemi è utile rendere alcuni interi, x, diventano tutti 1 se contiene 1 se rimangono 0 se è 0. Il motivo per cui lo faccio è così che posso tornare yoz simili:

// One of the two conditional values is now 0 
int conditionalA = mask&y; 
int conditionalB = ~mask&z; 

// One of the values is combined with 0 using | 
int out = conditionalA|conditionalB; 

return out; 

dove feci maschera così:

// Make any x other than 0 all 1s 
int mask = x; 
mask |= mask>>1; 
mask |= mask>>2; 
mask |= mask>>4; 
mask |= mask>>8; 
mask |= mask>>16; 

mask |= mask<<1; 
mask |= mask<<2; 
mask |= mask<<4; 
mask |= mask<<8; 
mask |= mask<<16; 

ci deve essere un modo migliore per rendere maschera tutti 1s o 0s ma non può pensare ad una più efficiente soluzione. Anche in questo caso, è importante che resti 0 0 se x è 0.

Edit: se le dichiarazioni non sono un'opzione

+0

Immagino che non sia possibile utilizzare le costanti letterali? – Jack

+0

Potrei, ma con ulteriori restrizioni (permesso solo di scrivere numeri tra 0x0 - 0xff e shift se hanno bisogno di essere più grandi). Non vedo come potrebbero essere d'aiuto anche se – asimes

+1

Dai una sbirciatina a questa raccolta di hack che girano a piccoli passi: http://graphics.stanford.edu/~seander/bithacks.html – vonbrand

risposta

6

Assumendo complemento a 2:

int mask = !x + ~0; 

Il ! Mappe qualsiasi valore diverso da zero per 0 e 0-1, poi aggiungiamo ~0 (-1) per ottenere -1 e 0 rispettivamente.

+0

Questo è perfetto, grazie – asimes

+0

Ah, era buono prima di 'int mask =! X + ~ 0;', non riesco a usarlo - – asimes

+0

@asimi sì, avrei dovuto lasciarlo da solo! Risolto, grazie. – ecatmur

3

ne dite:

x = (x | -x) >> 31; // Note this is implementation specific. 

Ok, sto usando - che non è permesso, quindi non è la risposta giusta qui. Lo lascerò qui come una novità.

+0

Non funziona, giusto? Se x è iniziato come '4', finisce con' 0xfffffffc'. –

+0

@JerryCoffin: lo farebbe. Ecco perché ha usato '-', non' ~ '. –

+0

@JerryCoffin Non sarebbe '0 | -0' che è '0 | 0'? –

2

Ecco uno funzionante penso (assume due complemento di aritmetica):

x = ~!!x + 1; 

Come sono arrivato lì?

Innanzitutto, !!x trasforma qualsiasi valore diverso da zero in 1 e 0 rimane 0. Quindi, utilizzando l'equivalenza del complemento a 2 per la negazione -x = ~x + 1, presto!

+0

Intelligente, ma un'altra parte del compito sta tentando di prendere l'abitudine di usare quantità minime di operatori, quindi vado avanti con 'mask =! X + ~ 0;'. Grazie però – asimes

+0

Se vuoi meno operatori, perché non 'mask =! X + 0xffffffff'? Modifica: mi dispiace - non ho visto la restrizione extra nel commento sopra. –

+0

Un'altra regola arbitraria non è in grado di scrivere letterali superiori a 0xff, altrimenti sarebbe ancora meglio – asimes