He escrito un script de Raku para llamar a la función erf en la biblioteca estándar de C:
use NativeCall; sub erf(num64) returns num64 is native { * }; say [0.5,1,2,3,4,-0.9].map: {erf($_.Num)};La salida de este script
(0.5204998778130465 0.8427007929497149 0.9953222650189527 0.9999779095030014 0.9999999845827421 -0.7969082124228322) coincide con la salida de C para todos los valores [0.5,1,2,3,4,-0.9] excepto 4 .
Para 4 , C genera 1.000000 mientras que Raku da 0.9999999845827421 .
Para probar la salida de 4 en C, ejecute este código:
#include <stdio.h> // Including header file for printf function #include <math.h> // Including header file for erf function int main (){ double param, result; param = 4.0; result = erf(param); printf("erf (%f) = %f\n", param, result); return 0; } ¿Tienes idea de lo que está pasando? También necesito generar 1.0 desde Raku.
Para el código C, cambie %f a %.99g para mostrar más dígitos. Esto revela erf(4) devuelve 0.9999999845827420852373279558378271758556365966796875.
%f solicita seis dígitos después del punto decimal. El valor se redondea para ajustarse a ese formato. %. number f solicita dígitos number después del punto decimal y siempre usa el formato "fijo". %. number g solicita number significativos y utiliza un formato "general" que cambia a notación exponencial cuando corresponde.
Para el código Raku, si desea una salida de "1.0" o "1.000000", deberá aplicar alguna solicitud de formato a la salida. No practico Raku, pero una breve búsqueda muestra que Raku tiene características similares a printf que puede usar, por lo que solicitar el formato %f debería duplicar la salida C.
Otra versión más que se basa en la explicación de @Eric sobre la precisión:
my $fmt = '%.6f'; printf [$fmt ~ ' '] x 5 ~ $fmt ~ "\n", [0.5,1,2,3,4,-0.9].map: {erf($_.Num)}; [$fmt ~ ' '] x 5 ~ $fmt ~ "\n" genera la cadena de formato "%.6f %.6f %.6f %.6f %.6f %.6f\n"
Producción
0.520500 0.842701 0.995322 0.999978 1.000000 -0.796908 O incluso más raku como lo propone raiph , usando el operador infijo xx :
printf "{'%.6f' xx 6} \n", [0.5,1,2,3,4,-0.9].map: {erf($_.Num)};Estás comparando manzanas con naranjas.
use NativeCall; sub erf(num64) returns num64 is native { * }; say .fmt("%f") for [0.5,1,2,3,4,-0.9].map: {erf($_.Num)} 0.520500 0.842701 0.995322 0.999978 1.000000 -0.796908 Está usando printf en C, si usa .fmt (la forma más fácil de decir sprintf en Raku), entonces también obtendrá 1.0 .