Я ищу способ сказать awk, чтобы сделать высокоточную арифметику в операции подстановки. Это включает в себя чтение поля из файла и замену его с шагом 1% на это значение. Однако я теряю точность там. Вот упрощенное воспроизведение проблемы:
$ echo 0.4970436865354813 | awk '{gsub($1, $1*1.1)}; {print}'
0.546748
Здесь у меня есть 16 цифр после десятичной точности, но awk дает только шесть. Используя printf, я получаю тот же результат:
$ echo 0.4970436865354813 | awk '{gsub($1, $1*1.1)}; {printf("%.16G\n", $1)}'
0.546748
Любые предложения о том, как получить желаемую точность?
gsub
необходимости. Проблемаgsub
работает со строками, а не числами, поэтому сначала выполняется преобразование с использованиемCONVFMT
значения по умолчанию%.6g
.Ответы:
Или скорее здесь:
это, вероятно, лучшее, что вы можете достичь. Используйте
bc
вместо этого для произвольной точности.источник
AWK
вы можете использовать-M
флаг и установитьPREC
значение на большое числоДля более высокой точности с (GNU) awk (с компиляцией bignum) используйте:
PREC = 100 означает 100 бит вместо 53 бит по умолчанию.
Если этот awk недоступен, используйте bc
Или вам нужно научиться жить с присущей неточности поплавков.
В ваших оригинальных строках есть несколько вопросов:
Формат преобразования из строки в (плавающее) число задается CONVFMT. Его значение по умолчанию
%.6g
. Это ограничивает значения до 6 десятичных цифр (после точки). Это применяется к результату изменения gsub$1
.Формат printf
g
удаляет завершающие нули:Обе проблемы могут быть решены с помощью:
Или же
Но не думайте, что это означает более высокую точность. Внутреннее представление чисел все еще является числом с плавающей точкой в двойном размере Это означает 53 бита точности, и при этом вы можете быть уверены только в 15 правильных десятичных цифрах, даже если много раз до 17 цифр выглядят правильно. Это мираж
Правильное значение:
Что также можно рассчитать с помощью (GNU) awk, если библиотека bignum была скомпилирована в:
источник