Ответ 1
Вы также можете прибегнуть к awk для форматирования:
echo "0.1 + 0.1" | bc | awk '{printf "%f", $0}'
или с самим awk, выполняющим математику:
echo "0.1 0.1" | awk '{printf "%f", $1 + $2}'
В Makefile я делаю что-то вроде следующего:
echo "0.1 + 0.1" | bc
(в реальном файле номера, конечно, динамические)
Он печатает .2
, но я хочу, чтобы он печатал 0.2
.
Я хотел бы сделать это, не прибегая к sed
, но я не могу найти, как получить bc
для печати нуля. Или bc
просто не в состоянии это сделать?
Вы также можете прибегнуть к awk для форматирования:
echo "0.1 + 0.1" | bc | awk '{printf "%f", $0}'
или с самим awk, выполняющим математику:
echo "0.1 0.1" | awk '{printf "%f", $1 + $2}'
Это может сработать для вас:
echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc
После быстрого просмотра источника (см. bc_out_num()
, строка 1461), я не вижу очевидного способа сделать ведущий 0
печатается, если целая часть 0
. Если я ничего не пропустил, это поведение не зависит от параметра, который можно изменить с помощью флага командной строки.
Короткий ответ: нет, я не думаю, что есть способ сделать bc
номера печати так, как вы хотите.
Я не вижу ничего плохого в использовании sed
, если вы все еще хотите использовать bc
. Следующее не выглядит так ужасно, ИМХО:
[[email protected]]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./'
0.2
Если вы действительно хотите избежать sed
, предложения eljunior's и choroba's довольно аккуратные, но они требуют зависящей от стоимости настройки, чтобы избежать конечных нулей. Это может быть или не быть проблемой для вас.
Я не могу найти ничего о формате вывода в документации. Вместо sed вы также можете использовать для printf:
printf '%3.1f\n' $(bc<<<0.1+0.1)
$ bc -l <<< 'x=-1/2; if (length (x) == scale (x) && x != 0) { if (x < 0) print "-",0,-x else print 0,x } else print x'
Это чистый bc
. Он определяет начальный нуль, сравнивая результат length
с scale
выражения. Он работает как с положительным, так и с отрицательным числом.
Это также будет обрабатывать отрицательные числа:
echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\./\10./'
это использует только bc и работает с отрицательными числами:
bc <<< "x=-.1; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
попробуйте:
for y in "0" "0.1" "-0.1" "1.1" "-1.1"; do
bc <<< "x=$y; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
echo;
done
Возможно, bc
на самом деле не лучший "калькулятор скамьи" для современной эпохи. Другие языки дадут вам больше контроля. Вот рабочие примеры, которые печатают значения в диапазоне (-1.0.. + 1.0) с начальным нулем. В этих примерах используется bc
, AWK
и Python 3
.
#!/bin/bash
echo "using bc"
time for (( i=-2; i<=+2; i++ ))
{
echo $(bc<<<"scale=1; x=$i/2; if (x==0||x<=-1||x>=1) { print x } else { if (x<0) { print \"-0\";-x } else { print \"0\";x } } ")
}
echo
echo "using awk"
time for (( i=-2; i<=+2; i++ ))
{
echo $(echo|awk "{printf \"%.1f\",$i/2}")
}
echo
echo "using Python"
time for (( i=-2; i<=+2; i++ ))
{
echo $(python3<<<"print($i/2)")
}
Обратите внимание, что версия Python примерно на 10 раз медленнее, если это имеет значение.
Основываясь на potongs answer,
Для дробных результатов:
echo "x=0.1 + 0.1; if(x<1 && x > 0) print 0; x" | bc -l
Обратите внимание, что отрицательные результаты отображаются неправильно. Для этого Aquarius Power имеет решение.
echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'
Это должно работать для всех случаев, когда результаты:
Пояснение:
Для всего, что начинается только с -.
, замените -.
на -0.
Для всего, что начинается только с .
, замените .
на 0.