Как сделать так, чтобы bc
десятичные дроби начинались с нуля?
$ bc <<< 'scale=4; 1/3'
.3333
Мне нужно 0,3333.
решение1
bc
изначально не поддерживает добавление нуля.
Обходной путь:
echo 'scale=4; 1/3' | bc -l | awk '{printf "%.4f\n", $0}'
0.3333
\n
– завершить вывод новой строкой.%f
- плавающая запятая%.4f
– количество отображаемых цифр. Это указывает 4 цифры после десятичной точки.
решение2
К сожалению, bc
написано так, что вы не можете. Это утверждение применимо и к его соседу dc
. Люди, как правило, предлагают в качестве решения использовать какой-либо текстовый редактор для изменения bc
вывода или использовать совершенно другой инструмент, например perl
или python
, который имеет другой синтаксис, но мне они кажутся слишком тяжелыми для такой простой задачи.
Из ваших других вопросов следует, что вы zsh
пользователь, поэтому я бы предложил zcalc
, который имеет очень похожий синтаксис для основных операций, таких как bc
:
$ zcalc -e '1/3'
0.333333
Сначала вам нужно загрузить эту функцию (например, внутри .zshrc
) и, возможно, вы захотите всегда обрабатывать все числа как числа с плавающей точкой с помощью -f
опции:
autoload -U zcalc
alias zcalc='zcalc -f'
В качестве бонуса вы можете определить специальную подсказку для калькулятора с ZCALCPROMPT
параметром, подробности смотрите здесь man zshcontrib
.
решение3
bc
можно убедить использовать начальный ноль:
for div in 10 1000; do
echo "scale=3;v=158/$div; if(v > -1 && v < 1) print 0,v,\"\n\" else print v, \"\n\"" | bc
done
решение4
Это решение типа «ремень и подтяжки», которое устраняет сбои, используя мой предыдущий ответ. Эта небольшая функция довольно разумно вычисляет, когда и где вставлять начальный 0 и отрицательный знак, и использует управляющий backspace
код для перемещения назад в напечатанном значении. Это не будет работать в режиме Posix -s|--standard
(или при печати на телетайпе!):
#!/usr/bin/env bc
# this is lz.bc
define lz(d) {
if (ibase != 10 || obase != 10) {
print "(io)base must be decimal (10)\n"
return -1
}
n=0; b=0; a=0
if (d<0) n=1 # negative
if (d>-1 && d<0) b=1 # below
if (d>0 && d<1) a=1 # above
print " ", d
for (i=length(d)+1; i>=0; i--) {
print "\b"
if(i==0 && (b || a)) print "0\b\b"
}
if(n) print "-"
print "\n"
return 0
}
v[0]=-.234
v[1]=.234
v[2]=-2.345
v[3]=2.345
v[4]=-123.4567
v[5]=123.456
for(x=0;x<6;x++) {
print v[x], " ... "
r=lz(v[x])
}
obase=16
r=lz(v[5])
quit
который при вызове отображает:
$ bc lz.bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
-.234 ... -0.234
.234 ... 0.234
-2.345 ... -2.345
2.345 ... 2.345
-123.4567 ... -123.4567
123.456 ... 123.456
(io)base must be decimal (10)