Для более высокой точности с (GNU) awk (с компиляцией bignum) используйте:
$ echo '0.4970436865354813' | awk -M -v PREC=100 '{printf("%.18f\n", $1)}'
0.497043686535481300
PREC = 100 означает 100 бит вместо 53 бит по умолчанию.
Если этот awk недоступен, используйте bc
$ echo '0.4970436865354813*1.1' | bc -l
.54674805518902943
Или вам нужно научиться жить с присущей неточности поплавков.
В ваших оригинальных строках есть несколько вопросов:
- Коэффициент 1,1 означает увеличение на 10%, а не на 1% (должно быть множителем 1,01). Я буду использовать 10%.
Формат преобразования из строки в (плавающее) число задается CONVFMT. Его значение по умолчанию %.6g
. Это ограничивает значения до 6 десятичных цифр (после точки). Это применяется к результату изменения gsub $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
Формат printf g
удаляет завершающие нули:
$ 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
Обе проблемы могут быть решены с помощью:
$ echo "$a" | awk '{printf("%.17g\n", $1*1.1)}'
0.54674805518902947
Или же
$ echo "$a" | awk -v CONVFMT=%.30g '{gsub($1, $1*1.1)}; {printf("%.17f\n", $1)}'
0.54674805518902947
Но не думайте, что это означает более высокую точность. Внутреннее представление чисел все еще является числом с плавающей точкой в двойном размере Это означает 53 бита точности, и при этом вы можете быть уверены только в 15 правильных десятичных цифрах, даже если много раз до 17 цифр выглядят правильно. Это мираж
$ echo "$a" | awk -v CONVFMT=%.30g '{gsub($1, $1*1.1}; {printf("%.30f\n", $1)}'
0.546748055189029469325134868996
Правильное значение:
$ echo "scale=18; 0.4970436865354813 * 1.1" | bc
.54674805518902943
Что также можно рассчитать с помощью (GNU) awk, если библиотека bignum была скомпилирована в:
$ echo "$a" | awk -M -v PREC=100 -v CONVFMT=%.30g '{printf("%.30f\n", $1)}'
0.497043686535481300000000000000