bash, bc modulo 不适用于 -l 标志
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27470210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash, bc modulo does not work with -l flag
提问by Saad Attieh
So I am trying to use bc
to calculate some logarithms but I also need to use it to calculate the modulus for something. Whilst making my script, I launched bc
to test it.
所以我试图用它bc
来计算一些对数,但我也需要用它来计算某些东西的模数。在制作我的脚本时,我开始bc
测试它。
Without any flags, bc <<< "3%5"
of course returns 3
.
没有任何标志,bc <<< "3%5"
当然返回3
.
But with bc -l
(loads math library so I can compute logarithms) any calculation of a%b
returns 0
where a
and b
can be any number but 0
.
但是使用bc -l
(加载数学库以便我可以计算对数)任何a%b
返回的计算,0
其中a
和b
可以是任何数字,但0
.
What's happening?
发生了什么?
回答by gniourf_gniourf
That's because, from the manual:
那是因为,从手册中:
expr % expr
The result of the expression is the "remainder" and it is com‐
puted in the following way. To compute a%b, first a/b is com‐
puted to scale digits. That result is used to compute a-(a/b)*b
to the scale of the maximum of scale+scale(b) and scale(a). If
scale is set to zero and both expressions are integers this
expression is the integer remainder function.
When you run bc
with the -l
flag, scale
is set to 20
. To fix this:
当您bc
使用-l
标志运行时,scale
设置为20
。要解决此问题:
bc -l <<< "oldscale=scale; scale=0; 3%5; scale=oldscale; l(2)"
We first save scale
in variable oldscale
, then set scale
to 0
to perform some arithmetic operations, and to compute a ln
we set scale
back to its old value. This will output:
我们首先保存scale
在变量中oldscale
,然后设置scale
为0
执行一些算术运算,并计算ln
我们设置scale
回它的旧值。这将输出:
3
.69314718055994530941
as wanted.
随心所欲。
回答by afenster
According to the bc
manual,
根据bc
手册,
expr % expr
The result of the expression is the "remainder" and it is computed
in the following way. To compute a%b, first a/b is computed to
scale digits. That result is used to compute a-(a/b)*b to the
scale of the maximum of scale+scale(b) and scale(a). If scale is
set to zero and both expressions are integers this expression is
the integer remainder function.
So what happens is that it tries to evaluate a-(a/b)*b
using the current scale
settings. The default scale
is 0 so you get the remainder. When you run bc -l
you get scale=20
and the expression a-(a/b)*b
evaluates to zero when using 20 fractional digits.
因此,它会尝试a-(a/b)*b
使用当前scale
设置进行评估。默认scale
值为 0,因此您可以获得余数。当您运行时,当您使用 20 个小数位时,bc -l
您会得到scale=20
并且表达式的a-(a/b)*b
计算结果为零。
To see how it works, try some other fractions:
要查看它是如何工作的,请尝试其他分数:
$ bc -l
1%3
.00000000000000000001
To make a long story short, just compare three outputs:
长话短说,只需比较三个输出:
Default scale
with -l
enabled (20):
默认scale
以-l
启用(20):
scale
20
3%5
0
1%4
0
Let's set scale
to 1:
让我们设置scale
为 1:
scale=1
3%5
0
1%4
.2
Or to zero (default without -l
):
或为零(默认没有-l
):
scale=0
3%5
3
1%4
1
回答by Thor
You could define a function that works in math mode by temporarily setting scale
to zero.
您可以通过临时设置scale
为零来定义一个在数学模式下工作的函数。
I have bc
aliased like this:
我有这样的bc
别名:
alias bc='bc -l ~/.bcrc'
Thus ~/.bcrc
is evaluated before any other expressions, so you can define functions in ~/.bcrc
. For example a modulus function:
因此~/.bcrc
在任何其他表达式之前计算,因此您可以在~/.bcrc
. 例如模数函数:
define mod(x,y) {
tmp = scale
scale = 0
ret = x%y
scale = tmp
return ret
}
Now you can do modulo like this:
现在你可以像这样做模:
echo 'mod(5,2)' | bc
Output:
输出:
1
回答by mpiffault
man bc :
男子公元前:
If bc is invoked with the -l option, a math library is preloaded and the default scale is set to 20.
如果使用 -l 选项调用 bc,则会预加载数学库并将默认比例设置为 20。
So maybe you should set the scale to 0 :
所以也许你应该将比例设置为 0 :
#bc
scale=0
10%3
1
回答by Unbeliever
For what it's worth, when I use bc -l
, I have the following functions defined:
对于它的价值,当我使用时bc -l
,我定义了以下函数:
define trunc(x) {auto s; s=scale; scale=0; x=x/1; scale=s; return x}
define mod(x,y) {return x-(y*trunc(x/y))}
That should give you a proper MOD
function, while keeping your scale intact. Of course, it won't help if you NEED to use the %
operator for some reason.
这应该给你一个适当的MOD
功能,同时保持你的秤完好无损。当然,如果您%
出于某种原因需要使用运算符,那也无济于事。
(That TRUNC
function is quite handy too, forming the basis for many other useful functions that are outside the scope of this answer.)
(该TRUNC
功能也非常方便,构成了本答案范围之外的许多其他有用功能的基础。)