bash,bc modulo不能与-l标志一起使用

时间:2014-12-14 14:16:42

标签: bash bc

所以我试图用bc来计算一些对数,但我还需要用它来计算某些东西的模数。在制作我的剧本时,我启动了bc来测试它。

没有任何标记,bc <<< "3%5"当然会返回3

但是使用bc -l(加载数学库以便我可以计算对数)a%b的任何计算都会返回0,其中ab可以是任意数字但是0

发生了什么事?

5 个答案:

答案 0 :(得分:13)

那是因为,从手册:

   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.

当您使用bc标记运行-l时,scale设置为20。解决这个问题:

bc -l <<< "oldscale=scale; scale=0; 3%5; scale=oldscale; l(2)"

我们首先将scale保存在变量oldscale中,然后将scale设置为0以执行某些算术运算,并计算ln我们设置{ {1}}回到原来的价值。这将输出:

scale

希望。

答案 1 :(得分:7)

根据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.

所以会发生的是它尝试使用当前a-(a/b)*b设置评估scale。默认scale为0,因此您可以获得余数。当您运行bc -l时,您将获得scale=20,并且当使用20个小数位时,表达式a-(a/b)*b的计算结果为零。

要了解它的工作原理,请尝试其他一些部分:

$ bc -l
1%3
.00000000000000000001

简而言之,只需比较三个输出:

启用了scale的默认-l(20):

scale
20

3%5
0

1%4
0

我们将scale设置为1:

scale=1

3%5
0

1%4
.2

或者为零(默认情况下没有-l):

scale=0

3%5
3

1%4
1

答案 2 :(得分:5)

您可以通过暂时将scale设置为零来定义一个在数学模式下工作的函数。

我有bc这样的别名:

alias bc='bc -l ~/.bcrc'

因此~/.bcrc在任何其他表达式之前被评估,因此您可以在~/.bcrc中定义函数。例如模数函数:

define mod(x,y) { 
  tmp   = scale
  scale = 0
  ret   = x%y
  scale = tmp
  return ret
}

现在你可以这样做模数:

echo 'mod(5,2)' | bc

输出:

1

答案 3 :(得分:3)

man bc:

  

如果使用-l选项调用bc,则会预加载数学库   默认比例设置为20.

所以也许你应该把比例设置为0:

#bc
scale=0
10%3
1

答案 4 :(得分:0)

关于它的价值,当我使用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))}

这应该为您提供适当的MOD功能,同时保持秤完整无缺。当然,如果由于某种原因需要使用%运算符,将无济于事。

TRUNC函数也非常方便,为该答案范围之外的许多其他有用函数奠定了基础。)