2014-12-13 3 views
1

У меня есть скрипт bash, который вычитает 0.0001 из больших чисел с помощью awk. Он не работает, если числа имеют более четырех знаков после запятой.Вычитание плавающих точек с помощью awk

Он использует эти аргументы AWK ...

balance=$(awk -vn1="$balance" -vn2="0.0001" 'BEGIN{print (n1-n2) }') 

Если $balance равно 1.44189949 число заканчивается 1.4418, и она должна быть 1.44179949 так что я сделал что-то не так.

Я никогда не занимался числами с плавающей запятой в bash раньше.

+0

кажется как AWK округляет результат. –

+0

Это не работает. 'fatal: недостаточно аргументов для удовлетворения строки формата. Я попытался:' balance = $ (awk -vn1 = "$ balance" -vn2 = "0.0001" 'BEGIN {printf ("12.8% f" (n1-n2))} ') ' –

+0

Произошла пропавшая запятая, но теперь я получаю очень странный вывод:' 12.81.441799' –

ответ

3

с использованием printf и изменить поведение округления по умолчанию awk с помощью "%.8f\n" для восьми округлых фигур.

awk -vn1="1.44189949" -vn2="0.0001" 'BEGIN{printf ("%.8f\n",n1-n2)}' 
+0

Это усекает 1 в начале с результатом: '0.44179949' –

+0

Я удалил« $ »с« $ 1.44189949 », что вызвало усечение. результаты должны быть хорошими – repzero

1

Для этого необходимо использовать bc, а не awk.

balance=$(echo $balance-0.0001 | /usr/bin/bc) 

Лучшее решение проблемы, как правило, является самым простым.

+1

'bc' делает десятичную математику. Большинство других языков (включая C++, PHP и awk) выполняют математику в двоичном формате. (Есть предложения добавить десятичную плавающую точку в C и C++, а частичная реализация доступна как расширение GCC.) – rici

+1

bc не всегда устанавливается по умолчанию в некоторой системе unix. – BMW

1

Если вы хотите, вы можете обойтись без awk как я сделал в следующем Баш скрипт:

balance=1.44189949 
printf "%.8f\n" $(bc -l <<< "$balance - 0.0001") 

Этот код использует bc, который является наиболее искусными в обработке чисел с плавающей запятой. Тогда printf заботится о округлении так, результат:

1.44179949 

Обратите внимание, что вход для bc является here string, который перенаправляется на команду.

2

Просто установите OFMT вы хотите, и напечатать результат, нет необходимости в Printf:

$ awk -v n1="1.44189949" -v n2="0.0001" -v OFMT="%.8f" 'BEGIN{print n1-n2}' 
1.44179949 
Смежные вопросы