Lo que hace la doble negación en C

Tuve una controversia sobre lo que los comstackdores “piensan” sobre esto:

a = 8; b = !!a; 

Entonces, es b == 0x01 ? ¿Es TRUE siempre 0x01 o puede ser 0xFF , 0xFFFF , 0xFFFFFFFF , etc.?

Si quiero extraer solo 0x00 si (a == 0) y 0x01 si (a > 0) funciona este enfoque de doble negación?

En otras palabras: para obtener el resultado solo 0 o 1, ¿qué es mejor usar?

a) a>0?1:0; b) !!a

Espero que entiendas mi pregunta.

!!a será 0 o 1, y será tipo int . Será 0 para cero a , y 1 de lo contrario.

En cuanto a sus opciones (a) y (b), no son equivalentes, debido a la posibilidad de a ser negativo. Aparte de eso, podrías argumentar que a > 0 ? 1 : 0 a > 0 ? 1 : 0 es más claro, pero en aplicaciones críticas para el rendimiento, !!a puede ser mejor, ya que no se ramificará, mientras que un condicional ternario podría volcar la tubería. Pero un buen comstackdor se optimizará de cualquier manera. Rara vez uso cualquiera ya que cosas como if (a) y if (!!a) son funcionalmente equivalentes.

No ha suministrado suficiente información para saber si !!a obra funciona para sus propósitos o no.

Usted declaró que realmente necesita el resultado de a > 0 . Sin embargo, esto no es equivalente a !!a si a está firmado y tiene un valor negativo. Si esto es posible, entonces la respuesta es obviamente “no”.

!!a es equivalente a a != 0 , no a a > 0 .

Sí, b == 1 . El resultado de cualquier operador booleano es siempre 0 o 1. Aunque puede hacerlo mejor …

Quiero extraer solo 0x00 if (a == 0) y 0x01 if (a> 0)

b = a > 0; refleja con mayor precisión su regla.

En términos de velocidad, creo que esto depende en gran medida del comstackdor y el procesador que está utilizando.

La expresión más larga produciría un ejecutable de 4 a 16 bytes más grande.

El resultado del operador de negación lógica ! es 0 si el valor de su operando se compara con 0, 1 si el valor de su operando se compara con 0. El resultado tiene el tipo int . La expresión !E es equivalente a (0==E) . C11 §6.5.3.3 5

b debajo tendrá el valor típico de 1 (o posible -1, ver más abajo).

 a = 8; b = !!a; 

Entonces, es b == 0x01 ?

Sí (* ver abajo)

¿Es TRUE siempre 0x01 o puede ser 0xFF , 0xFFFF , 0xFFFFFFFF , etc.?

En , true es una macro con la constante entera 1. TRUE no está definida por el estándar C. Varias implementaciones lo definen con el valor de 1. Podría tener otros valores. Ciertamente, debe ser no cero.

¿Qué es mejor usar?

 A) a>0?1:0 B) !!a 

Ambos resultan en un int con el valor de 0 o 1 . Se esperaría que un comstackdor de razonable a bueno genere el mismo código para ambos (si no está firmado). Use la forma que 1) se adhiere a su estándar de encoding de grupos o si no 2) mejor transmite el significado de código en ese punto. Una tercera opción que resulta en tipo (bool) :

 C) (bool) a 

Si a está firmado, entonces a>0?1:0 no es equivalente a !!a . a != 0 ? 1 :0 a != 0 ? 1 :0 es equivalente a !!a .


* Si b es un campo de bit con signo de 1 bit, b = !!8 tendrá el valor de -1.