Usando operadores bit a bit y supongo que suma y resta, ¿cómo puedo verificar si un entero con signo es positivo (específicamente, no negativo y no cero)? Estoy seguro de que la respuesta a esto es muy simple, pero simplemente no me viene a la mente.¿Cómo puedo verificar si un entero con signo es positivo?
Respuesta
Si realmente quiere un "es estrictamente positivo" predicado para el int n
sin utilizar los condicionales (suponiendo complemento a 2):
-n
tendrá el signo (arriba) bit igual sin
era estrictamente positivo, y claro en todos los demás casos excepton == INT_MIN
;~n
tendrán el bit de signo establece sin
era estrictamente positivo o 0, y claro en todos los demás casos, incluyendon == INT_MIN
;- ... así que
-n & ~n
tendrá el bit de signo establecido si n fue estrictamente positivo, y claro en todos los demás casos.
Aplicar una sin firmar cambio a convertir esto en un 0/1 respuesta:
int strictly_positive = (unsigned)(-n & ~n) >> ((sizeof(int) * CHAR_BIT) - 1);
EDIT: como puntos de CAF en los comentarios, -n
provoca un desbordamiento cuando n == INT_MIN
(aún asumiendo complemento a 2) El estándar C permite que el programa falle en este caso (por ejemplo, puede habilitar capturas para desbordamiento firmado usando GCC con la opción -ftrapv
). Casting n
a unsigned corrige el problema (la aritmética sin signo no causa desbordamientos). Así que una mejora sería:
unsigned u = (unsigned)n;
int strictly_positive = (-u & ~u) >> ((sizeof(int) * CHAR_BIT) - 1);
gracias, esto realmente me ayudó a llegar a lo que quería – Rowhawn
'-n' puede desbordarse en el caso de' n == INT_MIN'. – caf
Estrictamente, eso solo funciona en la aritmética de complemento de 2 (que son, les garantizo, los sistemas prácticamente significativos). Con un cero negativo (complemento de 1 o magnitud de signo), sus afirmaciones no son válidas. –
Comprueba el bit más significativo. 0 es positivo, 1 es negativo.
Considere cómo se representa la firma. A menudo se hace con complemento de dos o con un simple bit de signo - Creo que ambos podrían verificarse con un simple y lógico.
Compruebe que no es 0 y el bit más significativo es 0, algo así como:
int positive(int x) {
return x && (x & 0x80000000);
}
Asumiendo sizeof (int) == 4 ... –
¿Qué tal el retorno x && (x & MIN_INT)? – Ssancho
Si no puede utilizar los operadores de comparación obvios, entonces usted tiene que trabajar más duro:
int i = anyValue;
if (i && !(i & (1U << (sizeof(int) * CHAR_BIT - 1))))
/* I'm almost positive it is positive */
El primer término verifica que el valor no sea cero; el segundo verifica que el valor no tenga el bit inicial establecido. Eso debería funcionar para enteros de 2's, complementos de 1 o enteros de magnitud de signo.
Desafortunadamente, tiene un comportamiento indefinido;) - 2 elevado a la potencia de '(sizeof (int) * CHAR_BIT - 1)' ciertamente no es representable en 'int'. – caf
@caf: eso se puede resolver convirtiendo el 1 que se desplaza a 'unsigned int' con un sufijo U ... lo que significa que' i' también se convertirá en 'unsigned int'. El cambio de bit normalmente debería hacerse en cantidades sin signo de todos modos. –
Sí, eso arregla el UB - ahora solo tiene que preocuparse por el caso (¡incluso más teórico!) Donde 'int' y' unsigned int' tienen el mismo número de bits de valor ... – caf
- 1. ¿Cómo comprobar si un entero con signo es neg o pos?
- 2. ¿Cuál es la mejor forma de verificar si hay un entero positivo (PHP)?
- 3. ¿La forma más corta de verificar si una variable contiene un entero positivo usando PHP?
- 4. ¿Qué sucede cuando resta un entero sin signo de un entero con signo en C++?
- 5. ¿Cómo verificar si un valor es un número entero con plpgsql?
- 6. ¿Cómo puedo saber si un entero Java es nulo?
- 7. Entero con signo Little-Endian
- 8. ¿Cómo puedo verificar si un valor es un número?
- 9. Conversión de caracteres sin signo a entero con signo
- 10. ¿Cómo convierto una cadena hexadecimal en un entero con signo?
- 11. ¿Cómo puedo verificar si un identificador de MATLAB es válido?
- 12. ¿Cómo puedo verificar si un gráfico dirigido es acíclico?
- 13. ¿Por qué Count no es un entero sin signo?
- 14. ¿Cómo puedo verificar si existe un directorio?
- 15. ¿cómo puedo verificar si existe un archivo?
- 16. ¿Cuál es una buena manera de verificar si un doble es un número entero en C#?
- 17. Convertir 3 bytes en un entero con signo en C#
- 18. cómo comprobar si el carácter es un número entero
- 19. Cómo prefijar un número positivo con el signo más en PHP
- 20. Verificar si una cadena contiene un número entero
- 21. MySQL entero sin signo problemas aritméticos?
- 22. ¿Cómo detectar si un número dado es un número entero?
- 23. ¿Cuál es una mejor manera de verificar si una cadena es un número entero en iPhone?
- 24. C# ¿Cómo puedo verificar si existe una URL/es válida?
- 25. Compruebe si un entero es una potencia entera de otro
- 26. ¿Por qué no puedo verificar si un 'DateTime' es 'Nothing'?
- 27. Convierta un entero en una cadena con signo en Ruby
- 28. ¿Cómo puedo verificar si una BST es válida?
- 29. ¿Cómo puedo verificar si existe un procedimiento en un paquete?
- 30. ¿Es -5 un entero literal?
Solo un pensamiento: las respuestas a continuación son buenas, pero creo que no debe usarlas en la práctica porque en una CPU moderna, una comparación como "> 0" es solo 1 instrucción, y cualquiera de las respuestas a continuación van a ser instrucciones múltiples, posiblemente no haciendo uso de tuberías o núcleos separados. Son útiles si está haciendo su propio circuito para una comparación especial y necesita reducir el retraso de la ruta lógica. – Phil
Esto podría ser una pregunta de tarea que limita específicamente el uso de tales comparaciones :) – Alex
está relacionado con un problema de tarea más grande, esta es solo una parte que no puedo entender – Rowhawn