2014-12-14 20 views
6

Tak więc próbuję użyć bc, aby obliczyć logarytmy, ale muszę również użyć tego do obliczenia modulusa dla czegoś. Podczas tworzenia skryptu uruchomiłem bc, aby go przetestować.bash, bc modulo nie działa z flagą -l

Bez flag, bc <<< "3%5" oczywiście zwraca 3.

Ale z bc -l (biblioteka ładunki z matematyki, więc mogę obliczyć logarytmy) wszelkie obliczenia a%b zwrotów 0 gdzie a i b może być dowolna liczba, ale 0.

Co się dzieje?

Odpowiedz

11

To dlatego, że z instrukcji:

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. 

Po uruchomieniu bc z flagą -l, scale jest ustawiony na 20. Aby rozwiązać ten problem:

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

Najpierw zapisać scale w zmiennej oldscale, a następnie ustawić scale do 0 aby wykonać pewne operacje arytmetyczne, a do obliczenia ln ustawiamy scale powrotem do starej wartości. To wyświetli:

3 
.69314718055994530941 

zgodnie z potrzebami.

7

Według instrukcji 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. 

Więc co się dzieje, jest to, że stara się oceniać a-(a/b)*b przy użyciu bieżących scale ustawienia. Wartość domyślna scale wynosi 0, więc otrzymasz pozostałą część. Po uruchomieniu bc -l otrzymasz scale=20, a wyrażenie a-(a/b)*b zostanie obliczone na zero przy użyciu 20 cyfr ułamkowych.

Aby zobaczyć jak to działa, spróbować inne frakcje:

$ bc -l 
1%3 
.00000000000000000001 

Aby długie opowiadanie, wystarczy porównać trzy wyjścia:

domyślnych scale z -l włączony (20):

scale 
20 

3%5 
0 

1%4 
0 

Ustawmy scale na 1:

scale=1 

3%5 
0 

1%4 
.2 

Albo zero (domyślnie bez -l):

scale=0 

3%5 
3 

1%4 
1 
2

człowiek bc:

Jeżeli bc wywoływane jest z opcją -l, biblioteka matematyka jest fabrycznie i skala domyślna jest ustawione na 20.

Więc może należy ustawić skalę na 0:

#bc 
scale=0 
10%3 
1 
3

Można zdefiniować funkcję, która działa w trybie matematyki poprzez tymczasowe ustawienie scale do zera.

mam bc alias tak:

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

Zatem ~/.bcrc jest oceniany przed innymi wyrażeniami, więc można zdefiniować funkcje w ~/.bcrc. Na przykład funkcja moduł:

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

Teraz można zrobić modulo tak:

echo 'mod(5,2)' | bc 

wyjściowa:

1