true practices igual guidelines false best c++ c language-lawyer

c++ - practices - Conversión de NaN a Bool: ¿Verdadero o falso?



c++ core guidelines (1)

Tanto en C como en C ++, el comportamiento no está definido al convertir NAN a un tipo entero (distinto de bool ):

C99 6.3.1.4/1: Cuando un valor finito de tipo flotante real se convierte a un tipo entero distinto de _Bool , la parte fraccionaria se descarta (es decir, el valor se trunca hacia cero). Si el valor de la parte integral no puede representarse por el tipo de entero, el comportamiento no está definido .

C ++ 11 4.9 / 1: Un prvalue de un tipo de punto flotante se puede convertir en un prvalue de un tipo entero. La conversión trunca; es decir, se desecha la parte fraccionaria. El comportamiento no está definido si el valor truncado no se puede representar en el tipo de destino. [ Nota: Si el tipo de destino es bool , consulte 4.12. "Nota final "

En ambos idiomas, la conversión de NAN a bool (o _Bool ) da true (o 1 ):

C99 6.3.1.2/1: cuando cualquier valor escalar se convierte a _Bool , el resultado es 0 si el valor se compara con 0; De lo contrario, el resultado es 1.

C ++ 11 4.12 / 1: un valor cero, un valor de puntero nulo o un valor de puntero de miembro nulo se convierte en false ; Cualquier otro valor se convierte en true .

NAN no es un valor cero, y no se compara igual a cero.

¿Qué parte de la especificación de C ++, o la especificación flotante de IEEE, establece que un valor de NaN debe convertirse en true en lugar de falso?

Si miro el estándar de C ++, sección 4.12 Conversiones Booleanas , dice:

Un valor cero, un valor de puntero nulo o un valor de puntero de miembro nulo se convierte en falso; Cualquier otro valor se convierte en verdadero.

Ahora los flotadores IEEE dicen que NaN se compara con falso a cualquier otro valor. Entonces, si NaN es verdadero o falso depende de cómo haga su comparación (a continuación). Por lo tanto supongo que debe haber una mención explícita.

value == 0 ? false : true value != 0 ? true : false

Ahora, ¿qué pasa con la conversión a un número entero. El siguiente programa corto muestra que una variable NAN convertida en un entero da como resultado el entero mínimo, mientras que una constante se convierte a 0 (usando GCC). Esto parece extraño.

#include <iostream> #include <cmath> void write( double r, int i, bool b ) { std::cout << r << " == " << i << " == " << (b ? "True" : "False") << std::endl; } int main() { double value = NAN; write( value, value, value ); write( NAN, NAN, NAN ); }

Salida:

nan == -2147483648 == True nan == 0 == True

La conversión de un NaN a cero, pero la conversión de bool como True parece preocupante. Tampoco creo que algo como MatLab convierta un NaN a 0 usando una función como int16 .

Entonces, ¿cuáles son los detalles específicos de los estándares relevantes que establecen cómo NaN se convierte a valores booleanos y enteros?

También estoy etiquetando C, ya que si bien puede que no defina la conversión booleana, probablemente define una conversión y uso integral en un condicional y sospecho que C ++ seguirá las mismas reglas