Suponga que a , b , c y d se declaran double (o float ). ¿Son siempre verdaderas las siguientes expresiones?
! ( (a >= b) && (c <= d) ) || ( (ac) >= (bd) ) ! ( (a > b) && (c <= d) ) || ( (ac) > (bd) ) ! ( (a >= b) && (c < d) ) || ( (ac) > (bd) )¿Hay alguna garantía del IEEE 754 o del estándar C o C++ actual? ¿Y algún compilador optimizará esto como simplemente verdadero en el momento de la compilación? Me interesan sobre todo los valores normales, no tanto los valores subnormales o especiales.
Me parece que esto debería depender principalmente de los errores de redondeo durante la resta.
Para que el tercero produzca falso, debería ser suficiente tomar grandes iguales a y b y pequeños desiguales c y d , por ejemplo, a=1e30, b=1e30, c=1e-31, d=1e-30 .
EDITAR: Ok, para que el segundo produzca falso, por analogía con el tercero, debería ser suficiente tomar pequeños desiguales a y b y grandes iguales c y d , por ejemplo, a=1e-30, b=1e-31, c=1e30, d = 1e30 .
No tengo idea de un contraejemplo para la primera expresión...
Serge Rogatch dio contraejemplos a su segunda y tercera expresiones.
El primero, !(a >= b && c <= d) || ac >= bd , siempre es cierto en la aritmética IEEE 754, si a , b , c y d deben ser todos finitos. La resta de números finitos no puede producir un NaN . Así, un contraejemplo debe satisfacer a >= b && c <= d && ac < bd . Sin embargo, a >= b implica que ac >= bc , sea lo que sea c , y c <= d implica que bc >= bd , sea lo que sea b . La transitividad de >= se encarga del resto.
Puede tomar a = c = 1.0/0.0 y elegir arbitrariamente b y d como contraejemplo si relaja la condición de que a , b , c y d deben ser todos finitos. Todos los contraejemplos son esencialmente de esta forma.