Pour une plus grande précision avec (GNU) awk (avec bignum compilé en) utilisez:
$ echo '0.4970436865354813' | awk -M -v PREC=100 '{printf("%.18f\n", $1)}'
0.497043686535481300
PREC = 100 signifie 100 bits au lieu des 53 bits par défaut.
Si cet awk n'est pas disponible, utilisez bc
$ echo '0.4970436865354813*1.1' | bc -l
.54674805518902943
Ou vous devrez apprendre à vivre avec l'imprécision inhérente des flotteurs.
Dans vos lignes d'origine, il y a plusieurs problèmes:
- Un facteur de 1,1 correspond à une augmentation de 10% et non à 1% (devrait être un multiplicateur de 1,01). Je vais utiliser 10%.
Le format de conversion d'une chaîne en un nombre (flottant) est donné par CONVFMT. Sa valeur par défaut est %.6g
. Cela limite les valeurs à 6 chiffres décimaux (après le point). Ceci est appliqué au résultat du changement gsub de $1
.
$ a='0.4970436865354813'
$ echo "$a" | awk '{printf("%.16f\n", $1*1.1)}'
0.5467480551890295
$ echo "$a" | awk '{gsub($1, $1*1.1)}; {printf("%.16f\n", $1)}'
0.5467480000000000
Le format printf g
supprime les zéros de fin:
$ echo "$a" | awk '{gsub($1, $1*1.1)}; {printf("%.16g\n", $1)}'
0.546748
$ echo "$a" | awk '{gsub($1, $1*1.1)}; {printf("%.17g\n", $1)}'
0.54674800000000001
Les deux problèmes pourraient être résolus avec:
$ echo "$a" | awk '{printf("%.17g\n", $1*1.1)}'
0.54674805518902947
Ou
$ echo "$a" | awk -v CONVFMT=%.30g '{gsub($1, $1*1.1)}; {printf("%.17f\n", $1)}'
0.54674805518902947
Mais ne pensez pas que cela signifie une plus grande précision. La représentation numérique interne est toujours un flotteur en double taille. Cela signifie 53 bits de précision et avec cela, vous ne pouvez être sûr que de 15 chiffres décimaux corrects, même si plusieurs fois jusqu'à 17 chiffres semblent corrects. Voilà un mirage.
$ echo "$a" | awk -v CONVFMT=%.30g '{gsub($1, $1*1.1}; {printf("%.30f\n", $1)}'
0.546748055189029469325134868996
La valeur correcte est:
$ echo "scale=18; 0.4970436865354813 * 1.1" | bc
.54674805518902943
Ce qui pourrait également être calculé avec (GNU) awk si la bibliothèque bignum a été compilée dans:
$ echo "$a" | awk -M -v PREC=100 -v CONVFMT=%.30g '{printf("%.30f\n", $1)}'
0.497043686535481300000000000000