Programowanie w systemie UNIX/bc
bc (od ang. basic calculator) jest to język programowania umożliwiający:
- operowanie liczbami w dowolnych systemach liczbowych (wejście możliwe w systemie maksymalnie szesnastkowym, wyjście w dowolnie dużym), ale nie w formacie naukowym[1]
- operowanie liczbami dowolnej precyzji (zarówno przed, jak i po przecinku)
- wykonywanie skryptów
- wczytywanie danych z pliku lub standardowego wejścia. Pozwala to na użycie potoku (ang. pipe)
bc jest preprocesorem dla dc[2]
Podstawowe operacje
[edytuj]Uruchomianie
[edytuj]w konsoli wpisujemy
bc
Jest to podstawowy sposób uruchomienia. Standardowo liczba miejsc po przecinku (ang. scale) jest ustawiona na 0. Nie ładuje biblioteki standardowej.
Uruchomienie z opcją l :
- powoduje załadowanie przy uruchomieniu biblioteki standardowej, zawierającą np. funkcje trygonometryczne
- ustawia liczbę miejsc po przecinku dla dzielenia (ang. scale) na 20 zamiast domyślnego 0
- jest równoważna opcji --mathlib; ładuje standardową bibliotekę matematyczną[3]
bc -l
Pełna składnia:
bc [-hlwsqv] [długie_opcje] [plik...]
W ten sposób możemy wczytać skrypty bc
Kończenie pracy
[edytuj]W celu zakończenia pracy wpisujemy w bc:
quit
albo sekwencje klawiszy:
control-D
Ustawienia
[edytuj]limits
[edytuj]Za pomocą komendy:[4]
limits
sprawdzamy aktualne ustawienia:
BC_BASE_MAX = 2147483647 BC_DIM_MAX = 16777215 BC_SCALE_MAX = 2147483647 BC_STRING_MAX = 2147483647 MAX Exponent = 9223372036854775807 Number of vars = 32767
ibase i obase
[edytuj]Są to 2 specjalne zmienne (ang. special variables) określające podstawę (ang. base) liczb dla wejścia (ibase) i wyjścia (obase).
Najpierw sprawdźmy domyślne ustawienie:
ibase 10 obase 10
Zakres warto sci dla obase wynosi od 2 do 999 a dla ibase od 2 do 16.
Dzięki temu możemy wykonywać konwersje.
scale
[edytuj]Możemy zmienić poprzez:
- uruchomienie (
bc
lubbc -l
) - ręczne ustawienie:
scale= 20
- ustawienie w pliku
.bashrc
- w pliku .bashrc w katalogu domowym dodać
BC_ENV_ARGS=~/.bc
- potem
export BC_ENV_ARGS
- utworzyć plik
.bc
w katalogu domowym z jedną liniąscale=2
[5]
- w pliku .bashrc w katalogu domowym dodać
BC_LINE_LENGTH
[edytuj]Długość linii wydruku jest określona przez zmienną BC_LINE_LENGTH. Standardowo zmienna nie jest określona.
Przykład:
echo "scale=100;last=10;8/(1+(1/3))" | bc
powoduje:
6.000000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000001
W celu zmiany tego zachowania:
export BC_LINE_LENGTH=105
i ponownie
echo "scale=100;last=10;8/(1+(1/3))"|bc
otrzymujemy:
6.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
BC_ENV_ARGS
[edytuj]Tryby pracy
[edytuj]Interaktywny
[edytuj]bc
[edytuj]Uruchamiamy bc poprzez wpisanie w konsoli:
bc
otrzymujemy:
bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'.
Przykładowe obliczenie:
2^5-1
i wynik:
31
Kończymy pracę lub wprowadzamy nowe obliczenia.
Jeśli chcemy mieś większą dokładność to uruchamiamy z parametrem
bc -l
bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'.
Sprawdzamy jaka jest dokładność:
scale
wynik:
20
Wprowadzamy obliczenia:
33877456965431938318210482471113262183356704085033125021829876006886584214655562 / 237142198758023568227473377297792835283496928595231875152809132048206089502588927
wynik
.14285714285714285714
Zwiększamy dokładność:
scale=300
Ponownie obliczamy:
33877456965431938318210482471113262183356704085033125021829876006886584214655562 / 237142198758023568227473377297792835283496928595231875152809132048206089502588927
Wynik:
.1428571428571428571428571428571428571428571428571428571428571428571 42857142857147074022034435066432596572477650864745941127410090260162 88824806718611485924504671182507728691759096030983169039376702287127 38977340379914830920623570643668473851880233962854802649343258544237 37842209566161182966664275147
z poziomu bash'a
[edytuj]Z poziomu bash'a przesyłamy dane do bc korzystając z potoku:
echo '57+43' | bc
otrzymujemy wynik:
100
lub inny sposób: [5]
bc <<< 56.8+77.7
otrzymujemy:
134.5
Inny przykład:
bc -l <<< '10.5 / 1' 10.50000000000000000000
Inna metoda:
cru=$(echo $center_im+$r | bc -l)
Skryptowy
[edytuj]Bash'a
[edytuj]Skrypt Bash'a wysyła dane do bc. Odbiera wyniki i zapisuje je do zmiennych (num i den). Wyniki obliczeń z wykorzystaniem tych zmiennych zapisuje do pliku tekstowego[6]
Tutaj
- używamy backtick, aby uruchomić polecenie bc i przypisać dane wyjściowe do zmiennej
- W części dotyczącej opcji ustawiamy zmienne takie jak skala
- Operacje matematyczne są wykonywane w części wyrażeniowej
variable=`echo "options; expression" | bc`
Przykład
add=`echo "scale=4; $num1+$num2" | bc`
Cały skrypt:
#!/bin/bash # based on the code by Claude Heiland-Allen http://mathr.co.uk/blog/ rot=34 den=$(echo "2^${rot}-1" | bc) for i in $(seq 0 $((rot-1))) do num=$(echo "2^${i}" | bc) echo "${num}/${den}" echo echo done > "${rot}.txt"
bc
[edytuj]Przykłady
[edytuj]liczby zmiennoprzecinkowe w bash
[edytuj]dzięki bc możemy używać liczb zmiennoprzecinkowych w powłoce, także w skryptach[7][8]
#!/bin/bash
a=1.12
b=0.34
c=$(echo "$a * $b"|bc -l)
echo "$c"
Wynik :
b=0.34
c=$(echo "$a * $b"|bc -l)
echo "$c"
.3808
Kolejność wykonywania działań
[edytuj]1/3*2 .66666666666666666666 1/(3*2) .16666666666666666666
Komentarz dzielenie i mnożenia mają ten sam poziom[9] [10] więc wykonuje się je w kolejności od lewej do prawej
Może to powodować błąd w następującej sytuacji:
1/1*10^-6 .00000100000000000000 1/10^-6 1000000.00000000000000000000
Dzielenie
[edytuj]echo 'scale=25;57/43' | bc
wynik:
1.3255813953488372093023255
Konwersje
[edytuj]Zmiana e na 10
[edytuj]Jak przekształcić 1.0e-2
na 1.0*10^-2
?[11]
radius="1.0e-2.0" rim=`echo ${radius} | sed -e 's/[eE]+*/\\*10\\^/'` echo $rim
wynik:
1.0*10^-2.0
zmiana podstawy
[edytuj]Przekształcamy dziesiętną liczbę 12 (ibase = 10) na liczbę binarną (obase = 2)
$ echo 'obase=2;12' | bc
otrzymujemy:
1100
bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
obase=2
scale=300
3/14
.0011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011011010
scale=100
3.14159265358979323846264338327950288419716939937510
11.00100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001000100010011
zmiana typu
[edytuj]Zmiennoprzecinkowa do całkowitej (obcinanie = trunc):
echo '(4.2-1.3) / 1' | bc
wynik:
2
Nie działa dla liczb ujemnych i gdy scale > 0[12]
Pomoc
[edytuj]Podręcznik offline[13] w aktualnej wersji po polsku (ang. manual) otwiera się po wpisaniu w konsoli polecenia:
man bc
lub:
info bc
Zamykamy podręcznik klawiszem q
.
Pomoc online jest zwykle nieaktualna [14]
Wersja:
bc -v
otrzymujemy:
bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
Podobna informacja jest na 1 stronie podręcznika:
WERSJA Niniejszy podręcznik opisuje GNU bc w wersji 1.06.
Zobacz również
[edytuj]Źródła
[edytuj]- ↑ Stackoverflow: How to get bc to handle numbers in scientific (aka exponential) notation?
- ↑ command-line calculations using bc, by Rob Newcater
- ↑ stackoverflow question: how-can-i-compare-two-floating-point-numbers-in-bash
- ↑ bc - limits
- ↑ 5,0 5,1 Command line calculator, bc. Tip by Mark B
- ↑ tutorialsandyou : bash-bc
- ↑ linux journal : floating-point-math-bash by Mitch Frazier on July 30, 2008
- ↑ stackoverflow question: how-can-i-compare-two-floating-point-numbers-in-bash
- ↑ bc manual: Precedence
- ↑ Kolejność wykonywania działań w Wikipedii
- ↑ How to get bc to handle numbers in scientific (aka exponential) notation?
- ↑ Stackoverflow : bc truncate floating point number
- ↑ man (Unix)
- ↑ bc doc at opengroup