usar - División por cero: ¿Comportamiento indefinido o implementación definida en C y/o C++?
funciones en c++ (8)
¿Por qué lo haría?
Eso no tiene sentido matemáticamente, no es como si 1 / x se define como ∞ en matemáticas en general. Además, al menos necesitaría dos casos más: -1 / x y 0 / x no puede ser igual a ∞.
Vea la división por cero en general, y la sección sobre aritmética computacional en particular.
Respecto a la división por cero, los estándares dicen:
C99 6.5.5p5 - El resultado del operador / es el cociente de la división del primer operando por el segundo; El resultado del operador% es el resto. En ambas operaciones, si el valor del segundo operando es cero, el comportamiento no está definido.
C ++ 03 5.6.4 - El operador binario produce el cociente y el operador% binario produce el resto de la división de la primera expresión por la segunda. Si el segundo operando de / o% es cero, el comportamiento no está definido.
Si tomáramos los párrafos anteriores a su valor nominal, la respuesta es claramente un comportamiento indefinido para ambos idiomas. Sin embargo, si miramos más abajo en el estándar C99, vemos el siguiente párrafo que parece ser contradictorio (1):
C99 7.12p4: la macro INFINITY se expande a una expresión constante de tipo float que representa el infinito positivo o sin signo, si está disponible;
¿Los estándares tienen algún tipo de regla de oro donde el comportamiento indefinido no puede ser reemplazado por una declaración (potencialmente) contradictoria? Salvo eso, no creo que sea razonable concluir que si su implementación define la macro INFINITY, la división por cero se define como tal. Sin embargo, si su implementación no define dicha macro, el comportamiento es No definido.
Tengo curiosidad por saber cuál es el consenso (si lo hay) sobre este asunto para cada uno de los dos idiomas. ¿Cambiaría la respuesta si estamos hablando de división de enteros int i = 1 / 0
versus flotación de división de punto float i = 1.0 / 0.0
?
Nota (1) El estándar C ++ 03 habla sobre la biblioteca <cmath>
que incluye la macro INFINITY.
1/0 no es infinito, solo
lim 1/x = ∞ (x -> +0)
En pocas palabras, C99 (según sus citas) no dice nada acerca de INFINITY en el contexto de "implementación definida". En segundo lugar, lo que citó no muestra un significado incoherente de "comportamiento indefinido".
[Citar la página de comportamiento indefinido de Wikipedia] "En C y C ++, también se usa el comportamiento definido por la implementación, donde el estándar de idioma no especifica el comportamiento, pero la implementación debe elegir un comportamiento y debe documentar y observar las reglas que elija".
Más precisamente, el estándar significa "definido por la implementación" (creo que solo) cuando usa esas palabras con respecto a la declaración hecha desde que "definido por la implementación" es un atributo específico del estándar. La cita de C99 7.12p4 no mencionó "definida por la implementación".
[De C99 std (borrador tardío)] "comportamiento indefinido: comportamiento, en el uso de una estructura de programa no portátil o errónea o de datos erróneos, para los cuales esta Norma Internacional no impone requisitos"
Tenga en cuenta que no hay "ningún requisito" impuesto para un comportamiento indefinido!
[C99 ..] "Comportamiento definido por la implementación: comportamiento no especificado donde cada implementación documenta cómo se realiza la elección"
[C99 ..] "Comportamiento no especificado: uso de un valor no especificado u otro comportamiento donde esta Norma Internacional proporciona dos o más posibilidades y no impone requisitos adicionales sobre los que se eligen en ningún caso"
La documentación es un requisito para el comportamiento definido por la implementación.
Esta no era una pregunta pura de matemáticas, sino una pregunta C / C ++.
- De acuerdo con la norma IEEE 754, que todos los compiladores C / FPU modernos utilizan, tenemos
- 3.0 / 0.0 = INF
- 0.0 / 0.0 = NaN
- -3.0 / 0.0 = -INF
La FPU tendrá un indicador de estado que puede configurar para generar una excepción si así lo desea, pero esta no es la norma.
INF puede ser muy útil para evitar la ramificación cuando INF es un resultado útil. Ver discusión aquí
http://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
Las implementaciones que definen __STDC_IEC_559__
deben cumplir con los requisitos que figuran en el Anexo F, que a su vez requiere una semántica de punto flotante compatible con la norma IEC 60559. La Norma no impone requisitos sobre el comportamiento de la división de punto flotante por cero en las implementaciones que no definen __STDC_IEC_559__
, pero lo hace para aquellos que lo definen. En los casos en que IEC 60559 especifica un comportamiento pero el Estándar C no lo hace, el Estándar C requiere que un compilador que defina __STDC_IEC_559__
se comporte como se describe en el estándar IEC.
Según lo definido por IEC 60559 (o la norma IEEE-754 de EE. UU.) La división de cero por cero produce NaN, la división de un número de coma flotante por cero positivo o la constante literal cero da un valor INF con el mismo signo que el dividendo, y la división de un número de punto flotante por cero negativo produce un INF con el signo opuesto.
No veo ninguna contradicción. La división por cero no está definida, punto. No se menciona "... a menos que se defina INFINITY" en ninguna parte del texto citado.
Tenga en cuenta que en ninguna parte de las matemáticas se define que 1/0 = infinito . Uno podría interpretarlo de esa manera, pero es una interpretación personal, de estilo "atajo", en lugar de un hecho sólido.
Para la macro INFINITY: hay una codificación explícita para representar +/- infinito en el estándar IEEE754, que es si todos los bits de exponente están establecidos y todos los bits de fracción están borrados (si se establece un bit de fracción, representa NaN)
Con mi compilador, (int) INFINITY == -2147483648
, por lo que una expresión que se evalúa como int i = 1/0
definitivamente produciría resultados incorrectos si se devolviera INFINITIY
Solo tengo el draft de C99. En §7.12 / 4 dice:
La macro
INFINITY
se expande a una expresión constante de tipo float que representa infinito positivo o sin signo, si está disponible; de lo contrario, a una constante positiva de tipo
float
que se desborda en el momento de la traducción.
Tenga en cuenta que INFINITY
se puede definir en términos de desbordamiento de punto flotante, no necesariamente dividido por cero.