2014-12-14 4 views
6

Quindi sto cercando di utilizzare bc per calcolare alcuni logaritmi, ma ho anche bisogno di usarlo per calcolare il modulo per qualcosa. Durante la creazione del mio script, ho lanciato bc per testarlo.bash, modulo bc non funziona con -l flag

Senza bandiere, bc <<< "3%5" restituisce ovviamente 3.

Ma con bc -l (biblioteca carichi di matematica in modo da poter calcolare i logaritmi) qualsiasi calcolo di a%b rendimenti 0 dove a e b può essere qualsiasi numero, ma 0.

Cosa sta succedendo?

risposta

11

Questo perché, dal manuale:

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. 

Quando si esegue bc con la bandiera -l, scale è impostato su 20. Per risolvere questo problema:

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

Abbiamo innanzitutto salvare scale nella variabile oldscale, quindi impostare scale-0 per eseguire alcune operazioni aritmetiche, e per calcolare una ln abbiamo impostato scale torna al suo vecchio valore. Ciò produrrà:

3 
.69314718055994530941 

come desiderato.

7

Secondo il manuale 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. 

Quindi, ciò che accade è che si cerca di valutare a-(a/b)*b utilizzando le attuali scale impostazioni. Il valore predefinito scale è 0, quindi ottieni il resto. Quando esegui bc -l ottieni scale=20 e l'espressione a-(a/b)*b viene valutata a zero quando si utilizzano 20 cifre frazionarie.

Per vedere come funziona, provare alcune altre frazioni:

$ bc -l 
1%3 
.00000000000000000001 

Per fare una lunga storia breve, basta confrontare tre uscite:

predefinite scale con -l abilitato (20):

scale 
20 

3%5 
0 

1%4 
0 

Fissiamo scale-1:

scale=1 

3%5 
0 

1%4 
.2 

O a zero (default senza -l):

scale=0 

3%5 
3 

1%4 
1 
2

uomo bc:

Se bc viene richiamato con l'opzione -l, una libreria matematica è precaricato e la scala di default è impostato su 20.

Così forse si dovrebbe impostare la scala a 0:

#bc 
scale=0 
10%3 
1 
3

Si potrebbe definire una funzione che lavora in modalità matematica impostando temporaneamente scale a zero.

ho bc alias come questo:

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

Così ~/.bcrc viene valutata prima di qualsiasi altra espressione, in modo da poter definire le funzioni in ~/.bcrc. Ad esempio, una funzione di modulo:

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

ora si può fare modulo come questo:

echo 'mod(5,2)' | bc 

uscita:

1