【发布时间】:2013-12-31 18:17:09
【问题描述】:
如何使用 bc 截断浮点数
例如,如果我这样做了
echo '4.2-1.3' | bc
输出2.9我如何截断/使用 floor 来获得2
【问题讨论】:
如何使用 bc 截断浮点数
例如,如果我这样做了
echo '4.2-1.3' | bc
输出2.9我如何截断/使用 floor 来获得2
【问题讨论】:
控制除法小数位数的变量是scale。
因此,如果比例为 0(默认值),除以 1 将截断为 0 小数:
$ echo '(4.2-1.3) / 1 ' | bc
2
在其他运算中,小数位数是根据每个操作数的小数位数(小数位数)计算得出的。例如,在加法、减法和乘法中,得到的比例是两者中最大的:
$ echo ' 4.2 - 1.33333333 ' | bc
2.86666667
$ echo ' 4.2 - 1.333333333333333333 ' | bc
2.866666666666666667
$ echo ' 4.2000 * 1.33 ' | bc
5.5860
相反,在除法中,小数位数严格等于变量scale的值:
$ echo 'scale=0;4/3;scale=3;4/3;scale=10;4/3' | bc
1
1.333
1.3333333333
由于要恢复scale的值,最好定义一个函数(GNU语法):
$ echo ' define int(x){ os=scale;scale=0;x=x/1;scale=os;return(x) }
int( 4.2-1.3 )' | bc
2
或者使用较旧的 POSIX 语言:
$ echo ' define i(x){
o=scale;scale=0;x=x/1;scale=o;return(x)
}
i( 4.2-1.3 )' | bc
2
【讨论】:
尝试以下解决方案。它会毫无问题地截断小数点后的任何内容:
echo 'x = 4.2 - 1.3; scale = 0; x / 1' | bc -l
echo 'x = l(101) / l(10); scale = 0; x / 1' | bc -l
您可以通过直接对数字执行计算来缩短代码:
echo 'scale = 0; (4.2 - 1.3) / 1' | bc -l
echo 'scale = 0; (l(101) / l(10)) / 1' | bc -l
一般情况下,您可以使用此函数仅获取数字的整数部分:
define int(x) {
auto s;
s = scale;
scale = 0;
x /= 1; /* This will have the effect of truncating x to its integer value */
scale = s;
return (x);
}
将该代码保存到一个文件中(我们称之为int.bc)并运行以下命令:
echo 'int(4.2 - 1.3);' | bc -l int.bc
【讨论】:
如果scale 为 0,除以 1 可以正常工作(例如,如果您以 bc 开始 bc 并且不更改 scale)但如果 scale 为正数则失败(例如,如果您以bc -l 或增加scale)。 (请参阅下面的脚本。)对于一般解决方案,请使用 trunc 函数,如下所示:define trunc(x) { auto s; s=scale; scale=0; x=x/1; scale=s; return x }
说明在 bc -l 情况下如何被 1 除以自身失败的脚本,但 trunc 函数如何在向零截断时正常工作:
> bc -l
bc 1.06.95
[etc...]
for (x=-4; x<4; x+=l(2)) { print x,"\t",x/1,"\n"}
-4 -4.00000000000000000000
-3.30685281944005469059 -3.30685281944005469059
-2.61370563888010938118 -2.61370563888010938118
-1.92055845832016407177 -1.92055845832016407177
-1.22741127776021876236 -1.22741127776021876236
-.53426409720027345295 -.53426409720027345295
.15888308335967185646 .15888308335967185646
.85203026391961716587 .85203026391961716587
1.54517744447956247528 1.54517744447956247528
2.23832462503950778469 2.23832462503950778469
2.93147180559945309410 2.93147180559945309410
3.62461898615939840351 3.62461898615939840351
define trunc(x) { auto s; s=scale; scale=0; x=x/1; scale=s; return x }
for (x=-4; x<4; x+=l(2)) { print x,"\t",trunc(x),"\n"}
-4 -4
-3.30685281944005469059 -3
-2.61370563888010938118 -2
-1.92055845832016407177 -1
-1.22741127776021876236 -1
-.53426409720027345295 0
.15888308335967185646 0
.85203026391961716587 0
1.54517744447956247528 1
2.23832462503950778469 2
2.93147180559945309410 2
3.62461898615939840351 3
【讨论】:
bc <<< "scale=10;f=(3/55);scale=0;(312*f)/1"
使用/ 运算符。
echo '(4.2-1.3) / 1' | bc
【讨论】:
echo '(l(101)/l(10)) / 1' | bc -l 返回一个浮点数。
echo 'scale=0; (l(101)/l(10)) / 1' | bc -l,它仍然可以工作