c floating-point ieee-754 random-testing

Generación aleatoria de programas C con coma flotante



floating-point ieee-754 (2)

¿Alguien conoce un generador aleatorio de programas C que incluya cálculos de coma flotante?

Estoy buscando algo que se parezca un poco a Csmith , excepto que Csmith no genera expresiones de punto flotante, y que genera toneladas de otras construcciones, por lo que es un poco difícil de modificar. La generación de cálculos secuenciales sería un buen comienzo para mi propósito siempre que estos incluyan algunos de coma flotante. Condicionales sería incluso mejor, pero no necesitaría bucles, punteros o incluso arreglos.

Dado que muchos lenguajes usan una sintaxis similar a C, tal generador puede no ser específico de C. Incluso si es específico de otro lenguaje similar a C, podría ser capaz de procesar un programa generado para ese lenguaje en un texto. Programa C

EDITAR: aquí hay un fragmento de un programa generado por Csmith para aclarar lo que estoy buscando.

... int64_t *l_374 = &g_189; int32_t l_375 = (-1L); int i, j, k; l_375 &= ((g_106 == ((*l_374) = (&g_324[4] == l_373[0][0][5]))) < 0x80C8L); return (*g_207); ...

También debo aclarar que, si bien tomar un programa de Csmith y sustituir, digamos, int64_t con float puede dar un programa C sintácticamente correcto, es casi seguro que no proporcione un programa definido. Puedo probar si un programa sustituido contiene un comportamiento indefinido, pero esto no es barato, y si tengo que rechazar el 99% de los programas sustituidos porque no están definidos, el proceso será demasiado lento para ser útil.


Empecé con un fuzzer pequeño de coma flotante . Hace poco por ahora, pero tienes que comenzar con algo.

Aquí hay un ejemplo de uso para comparar compiladores que generan instrucciones SSE2, que, según afirmo, no tienen excusa para generar resultados diferentes:

#include <stdio.h> double x0 = 35945970.47e-83; double x1 = (973e-37+(5626073.612783921311173024e-76*231.106261545926274055e1*66390306733994e-1*420514.99786508*654374994.1249111e-35*5201.6039804e56)+(2.93604195+33e-50)+(969222843.32046212043603+1734e01)+(0166605914e8+6701040019050623e-23+32591206968562.6e-11+90771798.753788905)+(328e-49/944642906580982081e7)); int main(){ x0 = (((x1*534425399171e0)*(x1*x0*x0)*(x1*x0*57063248719.703555336277392e-36*x0*472e57*65189741246535e-1)*x1*(x1/22393742341e70)*(x1+x0+x0+x0))-((843193503867271987e3*61.949746266e23*x1*x1*x0)/(x1/x1))); x0 = ((x0+x1+x1+x1+x0)-(x0*506680.0005767722e66*396.650621163*70798334426455964.1*x1*305369e14)); x1 = 660098705340e-21; printf("%a/n", x0); }

Para este programa, gcc y clang (que en esta plataforma generan instrucciones SSE2) generan ejecutables que calculan lo mismo:

~/genfloat $ gcc t.c ; ./a.out 0x1.5c5a77a63c1d6p+430 ~/genfloat $ clang t.c ; ./a.out 0x1.5c5a77a63c1d6p+430

También pretendo probar un analizador estático que se supone que predice todos los resultados posibles que se pueden obtener con un programa compilado con instrucciones x87, derramando algunos resultados intermedios en ubicaciones de memoria de precisión doble de una manera impredecible:

~/genfloat $ frama-c -val -float-hex -all-rounding-modes t.c ... x0 ∈ [0x1.5c5a77a63c1cap430 .. 0x1.5c5a77a63c1e8p430]

Lo anterior es un reclamo fuerte que debe ser probado.


Mi programa manydl.c está haciendo algo muy similar (en enteros). Puede adaptarlo bastante fácilmente a sus necesidades.

Escribí eso como un pequeño truco para convencer a algunas personas, notablemente Jacques Pitrat , de que un sistema Linux puede dlopen un dlopen muy grande (más de cientos de miles) de objetos compartidos, ese programa genera código C aleatorio -enfocado en enteros- y compila y dlopen -s luego ejecuta muchos de ellos. Podría adaptarlo a las necesidades de coma flotante. manydl.c mi manydl.c para que genere programas C aleatorios pero que terminen, por lo que podría adaptarlo a float (simplemente elija operaciones que son terminantes y baratas, como yo lo hice).

Pregúntame más a la hora del café

(ya que somos colegas cercanos)