Estoy buscando una manera de decirle a awk que haga aritmética de alta precisión en una operación de sustitución. Esto implica leer un campo de un archivo y sustituirlo con un incremento del 1% en ese valor. Sin embargo, estoy perdiendo precisión allí. Aquí hay una reproducción simplificada del problema:
$ echo 0.4970436865354813 | awk '{gsub($1, $1*1.1)}; {print}'
0.546748
Aquí, tengo 16 dígitos después de la precisión decimal, pero awk da solo seis. Usando printf, obtengo el mismo resultado:
$ echo 0.4970436865354813 | awk '{gsub($1, $1*1.1)}; {printf("%.16G\n", $1)}'
0.546748
¿Alguna sugerencia sobre cómo obtener la precisión deseada?
gsub
es innecesario. El problema es quegsub
funciona en cadenas, no en números, por lo que primero se realiza una conversiónCONVFMT
, y el valor predeterminado para eso es%.6g
.Respuestas:
O más bien aquí:
es probablemente lo mejor que puedes lograr. Use en su
bc
lugar para una precisión arbitraria.fuente
AWK
, puede usar la-M
bandera y establecer elPREC
valor en un gran númeroPara mayor precisión con (GNU) awk (con bignum compilado) use:
El PREC = 100 significa 100 bits en lugar de los 53 bits predeterminados.
Si ese awk no está disponible, use bc
O necesitará aprender a vivir con la imprecisión inherente de los flotadores.
En sus líneas originales hay varios problemas:
CONVFMT proporciona el formato de conversión de una cadena a un número (flotante). Su valor predeterminado es
%.6g
. Eso limita los valores a 6 dígitos decimales (después del punto). Eso se aplica al resultado del cambio de gsub de$1
.El formato printf
g
elimina los ceros finales:Ambos problemas podrían resolverse con:
O
Pero no tenga la idea de que esto significa mayor precisión. La representación interna del número sigue siendo flotante en tamaño doble. Eso significa 53 bits de precisión y con eso solo puede estar seguro de 15 dígitos decimales correctos, incluso si muchas veces hasta 17 dígitos parecen correctos. Eso es un espejismo.
El valor correcto es:
Que también podría calcularse con (GNU) awk si la biblioteca bignum se ha compilado en:
fuente