Usando operatori bit a bit e suppongo addizione e sottrazione, come posso verificare se un intero con segno è positivo (in particolare, non negativo e non zero)? Sono sicuro che la risposta a questo è molto semplice, ma non mi viene in mente.Come posso verificare se un intero con segno è positivo?
risposta
Se si vuole veramente un "è strettamente positivo" predicato per int n
senza usare condizionali (supponendo complemento a 2):
-n
avrà il segno (in alto) è impostato il bit sen
era strettamente positivo, e chiaro in tutti gli altri casi eccetton == INT_MIN
;~n
avrà il bit di segno impostato sen
era strettamente positiva, o 0, e chiaro in tutti gli altri casi, tra cuin == INT_MIN
;- ... quindi
-n & ~n
avrà il bit di segno impostato se n era strettamente positivo e chiaro in tutti gli altri casi.
Applicare un senza segno passaggio a trasformare questo in un 0/1 risposta:
int strictly_positive = (unsigned)(-n & ~n) >> ((sizeof(int) * CHAR_BIT) - 1);
EDIT: come punti caf nei commenti, -n
causa un overflow quando n == INT_MIN
(ancora assumendo complemento a 2). Lo standard C consente al programma di fallire in questo caso (ad esempio, è possibile abilitare trap per overflow con segno tramite GCC con l'opzione -ftrapv
). La trasmissione n
alle correzioni senza segno risolve il problema (l'aritmetica non firmata non causa overflow). Quindi, un miglioramento sarebbe:
unsigned u = (unsigned)n;
int strictly_positive = (-u & ~u) >> ((sizeof(int) * CHAR_BIT) - 1);
grazie, questo mi ha davvero aiutato a ottenere ciò che volevo – Rowhawn
'-n' potrebbe traboccare nel caso di' n == INT_MIN'. – caf
Strettamente, questo funziona solo sull'aritmetica del complemento a 2 (che sono, vi concedo, i sistemi praticamente significativi). Con uno zero negativo (complemento di 1 o magnitudine del segno), le tue asserzioni non sono valide. –
Controllare il bit più significativo. 0 è positivo, 1 è negativo.
Considerare come viene rappresentata la firma. Spesso è fatto con complemento a due o con un semplice segno bit - Penso che entrambi potrebbero essere controllati con una logica semplice e.
Controllare che non è 0 e il bit più significativo è 0, qualcosa di simile:
int positive(int x) {
return x && (x & 0x80000000);
}
Supponendo sizeof (int) == 4 ... –
Che dire di return x && (x & MIN_INT)? – Ssancho
Se non è possibile utilizzare gli operatori di confronto evidenti, poi si deve lavorare di più:
int i = anyValue;
if (i && !(i & (1U << (sizeof(int) * CHAR_BIT - 1))))
/* I'm almost positive it is positive */
Il primo termine controlla che il valore non sia zero; il secondo controlla che il valore non abbia il bit iniziale impostato. Questo dovrebbe funzionare per i complementi a 2 complementi, a complemento d'oro oa numeri di segno.
Sfortunatamente, ha un comportamento indefinito;) - 2 elevato alla potenza di '(sizeof (int) * CHAR_BIT - 1)' non è certamente rappresentabile in 'int'. – caf
@caf: che può essere risolto convertendo il 1 spostato in 'unsigned int' con un suffisso U ... il che significa che' i' sarà convertito anche in 'unsigned int'. Il cambio di bit dovrebbe normalmente essere effettuato comunque su quantità non firmate. –
Sì, quello risolve l'UB - ora devi solo preoccuparti del caso (anche più teorico!) In cui 'int' e' unsigned int' hanno lo stesso numero di bit di valore ... – caf
- 1. Come verificare se un numero intero con segno è neg o pos?
- 2. Come verificare se un doppio è un numero intero
- 3. Come posso verificare se un numero è positivo o negativo in C#?
- 4. In C#, come verificare se una stringa contiene un intero?
- 5. come verificare se il carattere è un numero intero
- 6. Twig - Come verificare se la variabile è un numero/intero
- 7. Verificare se il valore intero è aumentato?
- 8. Come fare un hashcode (valore intero) positivo
- 9. Il modo più breve per verificare se una variabile contiene un numero intero positivo usando PHP?
- 10. Come rilevare se un dato numero è un numero intero?
- 11. Come posso verificare se un valore è un numero?
- 12. Come posso creare un valore letterale definito dall'utente per un tipo intero con segno?
- 13. VB2010 Come capire se un numero è un intero intero
- 14. Come posso verificare se un JSON è vuoto in NodeJS?
- 15. Come posso verificare se un IP è attivo in java?
- 16. Come posso verificare se un elemento non è definito?
- 17. Come modellare il numero intero con segno con BitVector?
- 18. Come posso verificare se un repository è nudo?
- 19. come posso verificare se esiste un file?
- 20. Come posso verificare se un grafico diretto è aciclico?
- 21. Come posso verificare se una stringa è un float?
- 22. Come posso verificare se un campo dell'editor CK è vuoto
- 23. Come posso verificare se un modulo PowerShell è installato?
- 24. Come posso verificare se un filehandle è aperto in Perl?
- 25. Come posso verificare se un array è nullo/vuoto?
- 26. Come posso verificare se un MSI particolare è installato?
- 27. Come posso verificare se un elenco è ordinato?
- 28. Come posso verificare se un URL è assoluto usando Python?
- 29. Come posso verificare se un socket è ancora aperto?
- 30. Come posso verificare se un UIViewController è attualmente visualizzato?
Solo un pensiero - le risposte qui sotto sono buone, ma penso che non si dovrebbe usare questi in pratica, perché su una CPU moderna, un confronto omogeneo "> 0" è solo 1 istruzioni, e una qualsiasi delle risposte sottostanti saranno istruzioni multiple, probabilmente non facendo uso di condutture o nuclei separati. Sono utili se stai creando il tuo circuito per un confronto speciale e hai bisogno di ridurre il ritardo del percorso logico. – Phil
Questa potrebbe essere una domanda a casa che limita specificamente l'uso di tali confronti :) – Alex
è correlato a un problema di compiti più grandi, questa è solo una parte di cui non riesco a capire – Rowhawn