可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I do something like the following in a Makefile:
echo "0.1 + 0.1" | bc
(in the real file the numbers are dynamic, of course)
It prints .2
but I want it to print 0.2
.
I would like to do this without resorting to sed
but I can't seem to find how to get bc
to print the zero. Or is bc
just not able to do this?
回答1:
You can also resort to awk to format:
echo "0.1 + 0.1" | bc | awk '{printf "%f", $0}'
or with awk itself doing the math:
echo "0.1 0.1" | awk '{printf "%f", $1 + $2}'
回答2:
This might work for you:
echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc
回答3:
After a quick look at the source (see bc_out_num()
, line 1461), I don't see an obvious way to make the leading 0
get printed if the integer portion is 0
. Unless I missed something, this behaviour is not dependent on a parameter which can be changed using command-line flag.
Short answer: no, I don't think there's a way to make bc
print numbers the way you want.
I don't see anything wrong with using sed
if you still want to use bc
. The following doesn't look that ghastly, IMHO:
[me@home]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./'
0.2
If you really want to avoid sed
, both eljunior's and choroba's suggestions are pretty neat, but they require value-dependent tweaking to avoid trailing zeros. That may or may not be an issue for you.
回答4:
I cannot find anything about output format in the documentation. Instead of sed, you can also reach for printf:
printf '%3.1f\n' $(bc<<<0.1+0.1)
回答5:
$ 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'
This one is pure bc
. It detects the leading zero by comparing the result of the length
with the scale
of the expression. It works on both positive and negative number.
回答6:
This one will also handle negative numbers:
echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\./\10./'
回答7:
echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'
This should work for all cases where the results are:
- "-.123"
- ".123"
- "-1.23"
- "1.23"
Explanation:
For everything that only starts with -.
, replace -.
with -0.
For everything that only starts with .
, replace .
with 0.
回答8:
For positive numbers, it may be as simple as printing (an string) zero:
$ echo '"0";0.1+0.1' | bc
0.2
avoid the zero if the number is bigger (or equal) to 1:
$ echo 'x=0.1+0.1; if(x<1){"0"}; x' | bc
0.2
It gets a bit more complex if the number may be negative:
echo 'x= 0.3 - 0.5 ; s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1) {"0"};x' | bc
-0.2
You may define a function and add it to a library:
$ echo 'define leadzero(x){auto s;
s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
return(x)};
leadzero(2.1-12.4)' | bc
-10.3
$ echo 'define leadzero(x){auto s;
s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
return(x)};
leadzero(0.1-0.4)' | bc
-0.3
回答9:
this only uses bc, and works with negative numbers:
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";
try it with:
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
回答10:
Probably, bc
isn't really the best "bench calculator" for the modern age. Other languages will give you more control. Here are working examples that print values in the range (-1.0..+1.0) with a leading zero. These examples use bc
, AWK
, and 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)")
}
Note that the Python version is about 10x slower, if that matters.
回答11:
Building on potongs answer,
For fractional results:
echo "x=0.1 + 0.1; if(x<1 && x > 0) print 0; x" | bc -l
Note that negative results will not be displayed correctly. Aquarius Power has a solution for that.