2010-10-22 9 views
5

Así que estoy retocando con C y quería ver si podía asignar un valor binario a un entero y usar la función printf() para generar un valor con signo o sin signo. Pero a pesar de obtener el mismo resultado, pensé que obtendría la mitad del valor para imprimir el firmado en comparación con el sin firmar. Estoy usando Code :: blocks y GCC.¿Por qué obtengo el mismo valor cuando imprimo este int?

¿printf() ignora el% i &% u y usa la definición de variable?

Código de ejemplo:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    signed int iNumber = 0b1111111111111111; 
    printf("Signed Int : %i\n", iNumber); 
    printf("Unsigned Int : %u\n", iNumber); 

    return 0; 
} 

mismo resultado si se cambia el int a firmar:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    unsigned int iNumber = 0b1111111111111111; 
    printf("Signed Int : %i\n", iNumber); 
    printf("Unsigned Int : %u\n", iNumber); 

    return 0; 
} 
+2

¿Estás seguro de que tus tipos int tienen solo 16 bits de ancho? –

+2

¿Qué es 'charCount'? – Donotalo

+2

Tenga en cuenta que la sintaxis constante binaria como '0b1111' no es el estándar ISO C. –

Respuesta

3

Debido a que los números positivos, la representación binaria en la mayoría de las plataformas es la misma entre firmado y sin firmar.

+0

para números positivos que encajan en un entero con signo (ya que otros números positivos no son representables como enteros con signo, por lo tanto su representación (no existente) como enteros con signo no puede ser igual a su representación como enteros sin signo) ;-) – ninjalj

+0

De hecho, aparte del nítido anterior, el estándar C lo requiere. – jilles

6

Supongo que charCount debe ser iNumber. Ambos programas tienen un comportamiento indefinido, ya que está utilizando el especificador de conversión incorrecto una vez.

En la práctica (para la mayoría de las implementaciones), printf depende de usted para decirle qué saltear de la pila; esto es necesario porque es una función de argumento variable. va_arg toma el tipo pop como el segundo parámetro

Los bits son los mismos entre los programas antes y después de la asignación. Entonces printf apunta a los mismos bits con punteros de diferentes tipos.

La razón por la que obtiene el mismo resultado para %i y %u es que el bit situado más a la izquierda no está configurado, por lo que se interpreta como positivo para ambos especificadores.

Por último, debe tener en cuenta que los literales binarios (0b) son una extensión de las CGC, no estándar de C.

+0

Gracias, lo cambié a '0xFFFFFFFF' y' 0x7FFFFFFF' (32 bits con el estándar C hex) y obtuve los resultados esperados. – ProfessionalAmateur

0

El resultado será diferente sólo para valores más altos que 0x7FFFFFFF como lo es en casi todos los sistemas del bit de mayor peso que se utiliza para marcar el signo. Para cálculos más rápidos dentro de la CPU, los otros bits están invertidos, así que 0xFFFFFFFF es -1 y 0x80000000 es -MAXINT-1 mientras que 0x7FFFFFFF es MAXINT.

2

En primer lugar, parece que está imprimiendo algo llamado charCount, sin error, y que la forma b de especificar un número no es estándar C. Comprobaría para asegurarse de que estaba haciendo lo que cree que es. Para una forma estándar de especificar patrones de bits como ese, utilice los formatos octal (número comienza con cero) o hexadecimal (número comienza con cero y x).

En segundo lugar, casi todas las computadoras tienen la misma representación binaria para un entero positivo y su equivalente sin signo, por lo que no habrá diferencia. Habrá una diferencia si el número es negativo, y eso depende típicamente del bit más significativo. Sus int s podrían ser de cualquier tamaño, desde 16 bits en un máximo, aunque en un escritorio, portátil o servidor que es muy probable que 32, y casi con toda seguridad, ya sea 32 o 64.

En tercer lugar, printf() no sabe nada sobre el tipo de la datos que le pasas Cuando se le llama, incluso es incapaz de conocer el tamaño de sus argumentos, o cuántos hay. Se deriva de los especificadores de formato, y si esos no están de acuerdo con los argumentos aprobados, puede haber problemas. Probablemente sea lo peor de printf().

+0

Incluso para un número negativo, obtendrá los mismos resultados en la práctica, ya que la asignación de firmado a no firmado no cambia el patrón de bits en complemento a dos. –

+0

@Matthew: Suponiendo que está imprimiendo el mismo patrón de bits, obtendrá diferentes resultados para números negativos, como -1 y 65535 para firmado y sin signo respectivamente para 16 bits de todos los bits, uno en complemento de dos. Asignar un número negativo a un resultado sin firmar en un gran número positivo, mientras que creo que asignar un valor grande sin signo a un firmado no está definido. –

+0

Debería haber sido más claro. Quise decir lo mismo entre los dos programas. –

0

Probablemente tengas entradas de 32 bits. En este caso, eso significa que su número tiene un valor de 32767 independientemente de si está firmado o no.

Cuestiones relacionadas