bc(1) | General Commands Manual | bc(1) |
bc - język kalkulatora dowolnej precyzji
bc [ -hlwsqv ] [długie-opcje] [ plik ... ]
bc jest językiem obsługującym obliczenia na liczbach dowolnej dokładności z interaktywnym wykonywaniem instrukcji. Istnieją pewne podobieństwa składni do języka programowania C. Przy pomocy opcji wiersza poleceń dostępna jest standardowa biblioteka matematyczna. Na żądanie, biblioteka matematyczna jest definiowana przed rozpoczęciem przetwarzania plików. bc rozpoczyna pracę przetwarzając kod z wszystkich plików wymienionych w wierszu poleceń, zachowując ich kolejność. Po przetworzeniu wszystkich plików, bc czyta ze standardowego wejścia. Całość kodu wykonywana jest w miarę czytania. (Jeśli plik zawiera polecenie zatrzymania procesora, to bc nie będzie prowadził odczytu ze standardowego wejścia).
Omawiana wersja bc zawiera kilka rozszerzeń w stosunku do tradycyjnych realizacji bc i standardu POSIX. Opcje wiersza poleceń mogą powodować, że rozszerzenia te będą wyświetlać ostrzeżenia lub będą odrzucane. Niniejszy dokument opisuje język akceptowany przez ten procesor bc. Rozszerzenia są w nim wyraźnie wyróżnione.
The most basic element in bc is the number. Numbers are arbitrary precision numbers. This precision is both in the integer part and the fractional part. All numbers are represented internally in decimal and all computation is done in decimal. (This version truncates results from divide and multiply operations.) There are two attributes of numbers, the length and the scale. The length is the total number of decimal digits used by bc to represent a number and the scale is the total number of decimal digits after the decimal point. For example:
.000001 ma długość 6 i dokładność 6.
1935.000 ma długość 7 i dokładność 3.
Liczby przechowywane są w dwu rodzajach zmiennych, zmiennych prostych i tablicach. Zarówno zmienne proste, jak i tablice mają nazwy. Nazwy zaczynają się od litery, po której następuje dowolna liczba liter, cyfr i znaków podkreślenia. Wszystkie litery muszą być małe. (Nazwy w pełni alfanumeryczne są rozszerzeniem. W POSIX-owym bc wszystkie nazwy są pojedynczymi małymi literami). Rodzaj zmiennej wynika z kontekstu, gdyż po nazwie każdej zmiennej tablicowej wystąpią nawiasy ([]).
Istnieją cztery zmienne specjalne: scale, ibase, obase oraz last. scale określa, jak niektóre operacje używają cyfr po kropce dziesiętnej. Domyślną wartością scale jest 0. ibase oraz obase określają podstawę pozycyjnego systemu liczbowego przy konwersji wejścia i wyjścia. Domyślną podstawą zarówno dla wejścia, jak i dla wyjścia jest 10. last (rozszerzenie standardu) jest zmienną, która przechowuje wartość ostatnio wydrukowanej liczby. Zmienne te będą omówione szczegółowo później, w odpowiedniej części. Wszystkie z nich mogą mieć przypisywane wartości, jak również mogą być używane w wyrażeniach.
Komentarze w bc rozpoczynają się od znaków /*, a kończą znakami */. Komentarze mogą zaczynać się w dowolnym miejscu i na wejściu pojawiają się jako pojedyncze spacje. (Powoduje to, że komentarze są ogranicznikami innych elementów wejścia. Na przykład, komentarz nie może znajdować się w środku nazwy zmiennej). Komentarze obejmują znaki nowej linii (końca linii) pomiędzy początkiem a końcem komentarza.
Do zapewnienia obsługi skryptów dla bc, jako rozszerzenie dodano komentarz w pojedynczym wierszu. Komentarz jednowierszowy rozpoczyna się znakiem # i rozciąga się do końca wiersza. Znak końca linii nie jest tu częścią komentarza i jest przetwarzany jak zwykle.
Liczbami posługują się wyrażenia i instrukcje. Ponieważ język został zaprojektowany jako interaktywny, instrukcje i wyrażenia wykonywane są niezwłocznie. Nie ma żadnego programu "głównego" ("main"). Zamiast tego, kod jest wykonywany zaraz po jego napotkaniu. (Funkcje, omówione szczegółowo dalej, są zdefiniowane po ich napotkaniu).
A simple expression is just a constant. bc converts constants into internal decimal numbers using the current input base, specified by the variable ibase. (There is an exception in functions.) The legal values of ibase are 2 through 36. (Bases greater than 16 are an extension.) Assigning a value outside this range to ibase will result in a value of 2 or 36. Input numbers may contain the characters 0–9 and A–Z. (Note: They must be capitals. Lower case letters are variable names.) Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number ZZZ always be the largest 3 digit number of the input base.
Pełne wyrażenia są podobne do występujących w wielu językach wysokiego poziomu. Ponieważ występuje tylko jeden rodzaj liczb, nie ma reguł określających użycie różnych typów. Zamiast tego istnieją reguły dotyczące dokładności wyrażeń. Każde wyrażenie ma określoną dokładność. Zależy ona od dokładności pierwotnych liczb, wykonywanego działania i, w wielu przypadkach, wartości zmiennej scale. Dopuszczalnymi wartościami zmiennej scale są liczby od 0 aż do maksymalnej liczby, jaka może być reprezentowana jako całkowita (integer) w języku C.
W podanych poniżej opisach dopuszczalnych wyrażeń, "wyrażenie" określa pełne wyrażenie a "zmienna" określa zmienną prostą lub tablicową. Zmienną prostą jest po prostu
Wyrażenia relacyjne są specjalnym rodzajem wyrażeń, zwracającym zawsze wartość 0 lub 1: zero jeśli relacja jest fałszywa, zaś 1 jeżeli jest prawdziwa. Mogą one występować w dowolnych dozwolonych wyrażeniach. (POSIX bc wymaga, by wyrażenia relacyjne były używane wyłącznie w instrukcjach if, while i for oraz aby było w nich użyte tylko jedno sprawdzenie relacji). Operatorami relacji są:
Dozwolone są także operacje logiczne. (POSIX bc NIE zawiera operacji logicznych). Wynikami wszystkich operacji logicznych są 0 lub 1 (dla fałszu i prawdy), tak jak dla wyrażeń relacyjnych. Operatorami logicznymi są:
Wyrażenia mają następujący priorytet (od najniższego do najwyższego):
operator ||, wiązanie lewe operator &&, wiązanie lewe operator !, niezwiązany operatory relacji, wiązanie lewe operator przypisania, wiązanie prawe operatory + i -, wiązanie lewe operatory *, / i %, wiązanie lewe operator ^, wiązanie prawe jednoargumentowy operator -, niezwiązany operatory ++ i --, niezwiązane
Kolejność wykonywania została dobrana tak, by programy zgodne z POSIX bc działały poprawnie. Powoduje to, że operatory relacyjne i logiczne, użyte w wyrażeniach przypisania, będą wykazywać niecodzienne zachowywanie. Weźmy następujące wyrażenie:
Większość programistów C uważałaby, że przypisze ono wynik operacji "3 < 5" (wartość 1) zmiennej "a". Tymczasem w bc nadaje ono wartość 3 zmiennej "a", a następnie porównuje 3 z 5. Używając operatorów relacji i operatorów logicznych z operatorami przypisania najlepiej jest posłużyć się nawiasami.
bc obsługuje jeszcze kilka innych wyrażeń specjalnych. Związane są one z funkcjami definiowanymi przez użytkownika i funkcjami standardowymi. Wszystkie one mają postać "nazwa(parametry)". Funkcje definiowane przez użytkownika opisano w sekcji Funkcje. Funkcjami standardowymi są:
Instrukcje (jak w większości języków algorytmicznych) umożliwiają sterowanie kolejnością wykonywania wyrażeń. W bc instrukcje wykonywane są bezzwłocznie, "tak szybko jak to jest możliwe". Wykonanie odbywa się gdy napotkano znak nowej linii i istnieje jedna lub więcej pełna instrukcja. W związku z takim natychmiastowym wykonaniem, znaki nowej linii są bardzo istotne w bc. W rzeczywistości, jako organiczniki instrukcji używane są zarówno znaki nowej linii, jak i średniki. Nieprawidłowo umieszczony znak nowej linii spowoduje błąd składni. Ponieważ znaki nowej linii rozdzielają instrukcje, możliwe jest ich ukrycie (przed interpretacją) przy pomocy znaku odwrotnego ukośnika. Sekwencja "\<nl>", gdzie <nl> jest znakiem nowej linii postrzegana jest przez bc jako znak zwykłej spacji zamiast znaku nowej linii. Poniżej umieszczono listę instrukcji bc i ich znaczenia (elementy umieszczone w nawiasach kwadratowych ([]) są opcjonalnymi częściami instrukcji):
wyrażenie1; while (wyrażenie2) {
instrukcja;
wyrażenie3; }
Te instrukcje nie są instrukcjami w tradycyjnym sensie tego terminu. Nie są one instrukcjami wykonywanymi. Ich funkcja jest wykonywana podczas "kompilacji".
Funkcje dostarczają sposobu definiowania obliczeń, które mogą być wykonane później. Funkcje w bc zawsze obliczają wartość i zwracają ją do miejsca wywołania. Definicje funkcji są "dynamiczne" w tym sensie, że funkcja pozostaje niezdefiniowana dopóki na wejściu nie zostanie odczytana jej definicja. Definicja ta jest następnie używana dopóki nie zostanie napotkana inna definicja funkcji o tej samej nazwie. Wówczas nowa definicja zastępuje starszą. Funkcja definiowana jest następująco:
define nazwa ( parametry ) { nowa_linia
lista_auto lista_instrukcji }
Wywołanie funkcji jest po prostu wyrażeniem postaci "nazwa(parametry)".
Parametry są liczbami lub tablicami (rozszerzenie). W definicji funkcji definiuje się równocześnie zero lub więcej jej parametrów przez podanie ich nazw rozdzielonych przecinkami. Liczby są jedynymi parametrami wywoływanymi przez wartość. Tablice podawane są w definicji parametrów przy pomocy notacji "nazwa[]". W wywołaniu funkcji parametry rzeczywiste dla parametrów numerycznych są pełnymi wyrażeniami. Do przekazywania tablic używana jest ta sama notacja, co przy definiowaniu parametrów typu tablicowego. Dana tablica przesyłana jest do funkcji przez wartość. Ponieważ definicje funkcji są dynamiczne, w trakcie wywoływania funkcji sprawdzana jest liczba i typy jej parametrów. Niezgodność liczby parametrów lub ich typów powoduje błąd wykonania. Błąd wykonania pojawi się także przy próbie wywołania niezdefiniowanej funkcji.
lista_auto jest opcjonalną listą zmiennych, do użytku "lokalnego". A oto składnia tej listy (jeśli występuje): "auto nazwa, ... ;". Średnik jest opcjonalny. Każda z nazw jest nazwą auto-zmiennej. Tablice mogą być podane przy użyciu takiej samej składni jak w parametrach. Na początku funkcji wartości tych zmiennych odkładane są na stosie. Następnie zmienne są inicjowane zerami i używane w czasie wykonywania funkcji. Przy zakończeniu funkcji zmienne są zdejmowane ze stosu, tak że przywracana jest ich pierwotna wartość (z momentu wywołania funkcji). Parametry te są faktycznie zmiennymi auto inicjowanymi wartościami dostarczonymi w wywołaniu funkcji. Zmienne typu auto różnią się od tradycyjnych zmiennych lokalnych, gdyż jeśli funkcja A woła funkcję B, to B może posługiwać się zmiennymi auto funkcji A po prostu używając tych samych nazw, chyba że funkcja B traktuje je jako zmienne auto. Ponieważ zmienne auto i parametry składowane są na stosie, to bc obsługuje funkcje rekurencyjne.
Ciało funkcji jest listą instrukcji bc. I znów, jak w części zasadniczej, instrukcje oddzielane są średnikami lub znakami nowej linii. Instrukcje return (powrót) powodują zakończenie funkcji i zwrócenie wartości. Istnieją dwa warianty instrukcji return. Pierwsza postać, "return", zwraca wartość 0 do wywołującego wyrażenia. Druga postać, "return ( wyrażenie )", oblicza wartość wyrażenia i zwraca ją do wyrażenia wołającego. Każda funkcja domyślnie kończy się niejawną instrukcją "return (0)". Pozwala to na funkcji na zakończenie działania i zwrócenie zera bez jawnej instrukcji powrotu.
Funkcje inaczej korzystają ze zmiennej ibase. Wszystkie stałe w obrębie ciała funkcji będą konwertowane przy zastosowaniu wartości ibase w momencie wywołania funkcji. Zmiany ibase w czasie wykonywania funkcji są ignorowane, z wyjątkiem funkcji standardowej read, która zawsze do konwersji liczb wykorzystuje bieżącą wartość ibase.
GNU bc zawiera kilka rozszerzeń związanych z funkcjami. Pierwszym jest nieco luźniejszy format definicji funkcji. Standard wymaga, by nawias otwierający znajdował się w tym samym wierszu, co słowo kluczowe define, a wszystkie pozostałe części w kolejnych wierszach. Opisywana tu wersja bc zezwala na dowolną liczbę znaków nowej linii przed i po nawiasie otwierającym funkcji. Na przykład, dozwolone są poniższe definicje.
define d (n) { return (2*n); } define d (n)
{ return (2*n); }
Funkcje mogą być zdefiniowane jako void. Funkcja void nie zwraca wartości, więc nie może być używana w miejscach, które wymagają wartości. Po wywołaniu funkcja void nie produkuje żadnego wyjścia. Słowo kluczowe void występuje pomiędzy słowem kluczowym define a nazwą funkcji. Na przykład prosimy rozważyć poniższy skrypt:
define py (y) { print "--->", y, "<---", "\n"; } define void px (x) { print "--->", x, "<---", "\n"; } py(1) --->1<--- 0 px(1) --->1<---
Także dodano wywoływanie tablic przez zmienną. Aby zadeklarować wywołanie przez zmienną tablicową, należy zadeklarować parametr tablicowy w definicji funkcji jako "*nazwa[]". Wywołanie funkcji jest takie samo, jak w przypadku wywołania przez wartość.
Jeżeli bc wywoływane jest z opcją -l, to wstępnie wczytywana jest biblioteka matematyczna (math library), a domyślna liczba cyfr dziesiętnych (scale) ustawiana jest na 20. Funkcje matematyczne obliczają swe wyniki z dokładnością określoną w momencie ich wywołania. Bibilioteka matematyczna definiuje następujące funkcje:
W powłoce /bin/sh, poniższe polecenie przypisuje wartość liczby "Pi" zmiennej środowiska pi.
Poniżej podano definicję funkcji wykładniczej używanej w bibliotece matematycznej. Funkcja ta napisana jest w bc standardu POSIX.
scale = 20 /* wykorzystuje fakt, że e^x = (e^(x/2))^2
Gdy x jest dostatecznie małe, używamy szeregu:
e^x = 1 + x + x^2/2! + x^3/3! + ... */ define e(x) {
auto a, d, e, f, i, m, v, z /* Sprawdzenie znaku x. */
if (x<0) {
m = 1
x = -x
} /* przewidywane x */
z = scale;
scale = 4 + z + .44*x;
while (x > 1) {
f += 1;
x /= 2;
} /* inicjowanie zmiennych */
v = 1+x
a = x
d = 1 for (i=2; 1; i++) {
e = (a *= x) / (d *= i)
if (e == 0) {
if (f>0) while (f--) v = v*v;
scale = z
if (m) return (1/v);
return (v/1);
}
v += e
} }
Poniższy kod posługuje się rozszerzonymi cechami bc do uzyskania prostego programu liczącego salda książeczki czekowej. Najlepiej byłoby zachować go w pliku, tak by mógł być wykorzystany wielokrotnie bez potrzeby każdorazowego przepisywania.
scale=2 print "\nProgram książeczki czekowej!\n" print " Pamiętaj, wpłaty są transakcjami ujemnymi.\n" print " Koniec - transakcja zerowa.\n\n" print "Saldo początkowe? "; bal = read() bal /= 1 print "\n" while (1) {
"bieżące saldo = "; bal
"transakcja? "; trans = read()
if (trans == 0) break;
bal -= trans
bal /= 1 } quit
Poniżej zamieszczono definicję rekurencyjnej funkcji silni.
define f (x) {
if (x <= 1) return (1);
return (f(x-1) * x); }
GNU bc może zostać skompilowany (przez opcję konfiguracji) tak, by posługiwał się biblioteką GNU edytora wejścia o nazwie readline lub też biblioteką BSD libedit. Umożliwia to użytkownikowi edycję wierszy przed wysłaniem ich do bc. Pozwala też na wykorzystanie historii poprzednio wprowadzonych wierszy. Przy wybraniu tej opcji bc zawiera dodatkową zmienną specjalną. Ta specjalna zmienna, history, przechowuje liczbę zachowywanych wierszy historii. Dla readline, wartość -1 oznacza, że przechowywana jest nieograniczona liczba wierszy historii. Ustawienie wartości history na liczbę dodatnią ogranicza liczbę przechowywanych wierszy historii do podanej liczby. Wartość zero wyłącza funkcję historii wprowadzonych wierszy. Wartością domyślną jest 100. Więcej informacji można znaleźć w podręcznikach użytkownika dla bibliotek GNU readline i history oraz BSD libedit. Nie można równocześnie włączyć zarówno readline, jak i libedit.
Niniejsza wersja bc została zbudowana, bazując na projekcie POSIX P1003.2/D11 i zawiera kilka różnic i rozszerzeń w stosunku do tego dokumentu i tradycyjnych realizacji. Nie jest wykonana w tradycyjny sposób, wykorzystujący polecenie dc(1). Wersja ta jest pojedynczym procesem, analizującym i uruchamiającym kod binarny będący tłumaczeniem programu. Istnieje "nieudokumentowana" opcja (-c) powodująca, że program wyświetla kod binarny na standardowym wyjściu zamiast wykonywania go. Używana była ona głównie do debuggowania analizatora składni i przy przygotowaniu biblioteki matematycznej.
Głównym źródłem różnic są rozszerzenia, w których jakaś cecha, możliwość programu jest rozbudowana w celu dodania funkcjonalności, oraz dodatki, gdzie dodano nowe możliwości. Poniżej podano listę różnic i rozszerzeń.
a = 1 b = 2
{ a = 1
b = 2 }
ma jeden blok wykonania. Każdy z błędów wykonania przerywa wykonywanie bieżącego bloku wykonania. Ostrzeżenie w trakcie wykonywania nie przerywa bieżącego bloku.
Poniżej podano obecne ograniczenia opisywanego procesora bc. Niektóre z nich mogą być zmienione podczas instalacji. Faktyczne ograniczenia można sprawdzić za pomocą instrukcji limits (ograniczenia).
bc przetwarza następujące zmienne środowiska:
Jeżeli któryś z plików podanych w wierszu poleceń nie może zostać otwarty bc zgłosi, że plik ten jest niedostępny i przerwie pracę. Istnieją też komunikaty diagnostyczne kompilacji i wykonania, które powinny być zrozumiałe.
Obsługa błędów (error recovery) nie jest jeszcze bardzo dobra.
Błędy proszę zgłaszać (w jęz.angielskim) na adres bug-bc@gnu.org. Proszę się upewnić, że pole tematu wiadomości zawiera gdzieś słowo "bc".
Philip A. Nelson philnelson@acm.org
Autor chciałby podziękować Steve'owi Sommars (Steve.Sommars@att.com) za jego szeroką pomoc w testowaniu tej implementacji. Podsunął on wiele cennych sugestii. Dzięki jego zaangażowaniu jest to o wiele lepszy produkt.
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Wojtek Kotwica <wkotwica@post.pl> i Robert Luberda <robert@debian.org>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres manpages-pl-list@lists.sourceforge.net.
11 czerwca 2006 r. | Projekt GNU |