proporcion numeros hacer edades dev comparar comparador comparación comparaciones comparacion como asignacion c comparison int ambiguity

numeros - ¿Ambigüedad en las comparaciones numéricas(en C)?



dev c++ comparar numeros (8)

No estoy muy familiarizado con la programación en C (solo he hecho algunos proyectos pequeños en el lenguaje), sin embargo, mi profesor dijo algo sobre su comportamiento hoy que me dejó un poco confundido.

Lo que dijo fue que este código a veces no imprime nada (copié exactamente lo que había en el pizarrón, creo que es un seudocódigo para C ya que "imprimir" no está en C):

int a = ___________; int b = ___________; if (a < b) print (“<“); if (a > b) print (“>”); if (a==b) print(“=”);

Básicamente, hay algo que podrías almacenar en esas variables int donde no se cumpliría ninguna de estas condiciones (el _ _ _ no es un código real, obviamente, simplemente representa que algo está ahí). No necesariamente tiene que ser un número int que llene esos espacios en blanco ... podría ser cualquier cosa en el mundo (y puede haber cosas que sucedieron antes de este código).

¿Qué es lo que podría llenar esos espacios en blanco y no produciría ningún resultado, y por qué?

ps - tenía algo que ver con un desbordamiento, comportamiento indefinido, error fuera de límites, o algo por el estilo

pps - Tengo serios problemas para creer que este profesor estaba equivocado. Él es más experto en programación que cualquier persona con la que haya estado en contacto. Estoy convencido de que hay algunos casos en que esto es cierto.


ps - podría haber tenido algo que ver con un desbordamiento?

Creo que esto es lo que tu profesor quiso decir:

#include <stdio.h> #include <stdint.h> int main(int argc, char** argv) { uint8_t a = 100; uint8_t b = 200; a = a + b; /* a = 300 in your head. This overflows, so 300-256=44 */ if ( a > b ) { printf("%u > %u", a, b); } else if ( a < b ) { printf("%u < %u", a, b); } else { printf("%u == %u", a, b); } return 0; }

Específicamente, estoy usando un entero sin signo de 8 bits de ancho fijo, que puede contener un máximo de 8 bits (sorpresa) que representa 256 como el entero más grande posible. Puede desbordar este campo al agregarle una cantidad que no se puede representar en este tamaño, en cuyo caso lo que le queda es un efecto envolvente.

No existe una ambigüedad real en la lógica de comparación si, ya que en realidad es parte del procesador (si se traduce en una de las combinaciones de instrucción de comparación / salto). El problema es que puede haberlo programado esperando razonablemente que funcione, sin darse cuenta de que las representaciones numéricas en una computadora tienen representaciones fijas. No puedo ver nada que pueda poner en esos registros que posiblemente escaparían de "menos, mayor o igual".

Tenga en cuenta que he utilizado los enteros de tamaño fijo introducidos por C99 para mayor claridad y tamaños de números pequeños para que podamos hacerlo en nuestra cabeza.


Dado que "puede haber cosas que sucedieron antes de este código" ...

#include <stdio.h> #include <math.h> int main(void) { #define int float int a = nanf(NULL); int b = nanf(NULL); if (a < b) printf("</n"); if (a > b) printf(">/n"); if (a == b) printf("==/n"); return 0; }


Para int esto no es cierto, porque no tienen valores "especiales".


Si tiene una arquitectura con números enteros en el complemento uno, existen dos ceros: uno con todo el bit establecido en 0 y uno con todo el bit establecido en 1, también conocido como cero positivo y negativo. Ambos ceros deberían ser iguales, pero un compilador defectuoso puede no ver eso ;-)


Supongo que es la parte lo que importa. Si la parte subrayada contiene el comportamiento de los resultados de código INDEFINIDO, y el código siguiente con comparaciones se optimiza mediante un compilador "inteligente" con el comportamiento indefinido, el comportamiento final de este fragmento de código no está definido. Y no imprimir nada es un comportamiento razonable e indefinido.

ps Según Wikipedia, la división por cero da como resultado un comportamiento indefinido, aunque la mayoría de los compiladores lo definen como un error. Y el desbordamiento de enteros con signo IIRC también causa un comportamiento indefinido, aunque nuevamente esto generalmente causa una excepción de tiempo de ejecución o incluso un error de compilación. Entonces, si a y b son declarados como

int a = 1 / 0; int b = INT_MAX + 1;

la situación que describe su profesor puede ocurrir. Pero recuerde, el comportamiento no está definido, por lo que sea lo que sea que elija el compilador para que el programa se comporte, se puede considerar que cumple con el estándar.


Tal vez la definición de print es:

void print(const char*) { }


Todo lo que se necesita es que una de las inicializaciones int genere una excepción en tiempo de ejecución. El programa terminará antes de cualquiera de las pruebas de comparación. P.ej

int b = *(int *)0;


a = 0, b = 5 / a : divide by zero