bc(1) General Commands Manual bc(1) NUME bc - un limbaj de calcul cu precizie arbitrara SINTAXA bc [ -hlwsqv ] [opiuni-lungi] [ fiier ... ] DESCRIERE bc este un limbaj care accepta numere cu precizie arbitrara cu execuie interactiva a instruciunilor. Exista unele asemanari in sintaxa cu limbajul de programare C. O biblioteca de matematica standard este disponibila prin opiune de linie de comanda. Daca se solicita, biblioteca de matematica este definita inainte de procesarea oricaror fiiere. bc incepe prin procesarea codului din toate fiierele enumerate in linia de comanda, in ordinea enumerata. Dupa ce toate fiierele au fost procesate, bc citete de la intrarea standard. Tot codul este executat pe masura ce este citit; (daca un fiier conine o comanda de oprire a procesorului, bc nu va citi niciodata de la intrarea standard). Aceasta versiune a bc conine mai multe extensii care depaesc implementarile bc tradiionale i proiectul de standard POSIX. Opiunile din linia de comanda pot face ca aceste extensii sa afieze un avertisment sau sa fie respinse. Acest document descrie limbajul acceptat de acest procesor. Extensiile vor fi identificate ca atare. OPIUNI -h, --help Afieaza modul de utilizare i iese. -i, --interactive Foreaza modul interactiv. -l, --mathlib Definete biblioteca matematica standard. -w, --warn Furnizeaza avertismente pentru extensiile la POSIX bc. -s, --standard Proceseaza exact in limbajul POSIX bc. -q, --quiet Nu afieaza mesajul normal de bun venit in GNU bc. -v, --version Afieaza numarul versiunii i drepturile de autor i iese. NUMERE Cel mai de baza element in bc este numarul. Numerele sunt numere cu precizie arbitrara. Aceasta precizie este atat in partea intreaga, cat i in partea fracionara. Toate numerele sunt reprezentate intern in zecimal i toate calculele sunt efectuate in zecimal; (aceasta versiune trunchiaza rezultatele operaiilor de imparire i multiplicare). Exista doua atribute ale numerelor, lungimea i scala. Lungimea este numarul total de cifre zecimale utilizate de bc pentru a reprezenta un numar, iar scala este numarul total de cifre zecimale dupa punctul zecimal. De exemplu: .000001 are o lungime de 6 i o scala de 6. 1935.000 are o lungime de 7 i o scala de 3. VARIABILE Numerele sunt stocate in doua tipuri de variabile, variabile simple i matrice. Atat variabilele simple, cat i variabilele matrice sunt denumite. Numele incep cu o litera urmata de orice numar de litere, cifre i liniue de subliniere. Toate literele trebuie sa fie in minuscule. Numele alfanumerice complete sunt o extensie; in bc POSIX toate numele sunt formate dintr-o singura litera minuscula). Tipul de variabila este clar in funcie de context, deoarece toate numele variabilelor de tip matrice vor fi urmate de paranteze drepte ([]). Exista patru variabile speciale, scale, ibase, obase, i last. scale definete modul in care unele operaii utilizeaza cifrele dupa punctul zecimal. Valoarea implicita a lui scale este 0. ibase i obase definesc baza de conversie pentru numerele de intrare i ieire. Valoarea implicita atat pentru intrare, cat i pentru ieire este baza 10. last (o extensie) este o variabila care are valoarea ultimului numar afiat. Acestea vor fi discutate mai detaliat acolo unde este cazul. Toate aceste variabile pot avea valori atribuite, precum i utilizate in expresii. COMENTARII Comentariile din bc incep cu caracterele /* i se termina cu caracterele */. Comentariile pot incepe oriunde i apar ca un singur spaiu in textul de intrare; (acest lucru face ca comentariile sa delimiteze alte elemente de intrare - de exemplu, un comentariu nu poate fi gasit in mijlocul unui nume de variabila). Comentariile includ orice linii noi (sfarit de linie) intre inceputul i sfaritul comentariului. Pentru a oferi suport pentru utilizarea scripturilor pentru bc, a fost adaugat un comentariu pe o singura linie ca extensie. Un comentariu pe o singura linie incepe la un caracter # i continua pana la urmatorul capat de linie. Caracterul de sfarit de linie nu face parte din comentariu i este procesat in mod normal. EXPRESII Numerele sunt manipulate prin expresii i instruciuni. Deoarece limbajul a fost conceput pentru a fi interactiv, instruciunile i expresiile sunt executate cat mai curand posibil. Nu exista un program ,,principal". In schimb, codul este executat pe masura ce este intalnit; (funciile, discutate in detaliu mai tarziu, sunt definite atunci cand sunt intalnite). O expresie simpla este doar o constanta. bc convertete constantele in numere zecimale interne folosind baza de intrare curenta, specificata de variabila ibase.; (exista o excepie in funcii). Valorile valide pentru ibase sunt de la 2 la 36; (bazele mai mari de 16 sunt o extensie). Atribuirea unei valori in afara acestui interval pentru ibase va avea ca rezultat o valoare de 2 sau 36. Numerele de intrare pot conine caracterele 0-9 i A-Z. - Nota: Acestea trebuie sa fie in majuscule. Literele minuscule sunt nume de variabile. - Numerele cu o singura cifra au intotdeauna valoarea cifrei indiferent de valoarea lui ibase, (de exemplu, A = 10.) Pentru numerele cu mai multe cifre, bc schimba toate cifrele de intrare mai mari sau egale cu ibase la valoarea ibase-1. Acest lucru face ca numarul ZZZ sa fie intotdeauna cel mai mare numar de 3 cifre din baza de intrare. Expresiile complete sunt similare cu multe alte limbaje de nivel inalt. Deoarece exista un singur tip de numar, nu exista reguli pentru amestecarea tipurilor. In schimb, exista reguli privind scala expresiilor. Fiecare expresie are o scala. Aceasta este derivata din scala numerelor originale, operaia efectuata i, in multe cazuri, valoarea variabilei scale. Valorile legale ale variabilei scale sunt de la 0 la numarul maxim reprezentabil de un numar intreg C. In urmatoarele descrieri ale expresiilor valide, ,,expr" se refera la o expresie completa, iar ,,var" se refera la o variabila simpla sau la o matrice. O variabila simpla este doar o nume iar o variabila matrice este specificata ca nume[expr] Cu excepia cazului in care se menioneaza in mod specific, scala rezultatului este scara maxima a expresiilor implicate. - expr Rezultatul este negaia expresiei. ++ var Variabila este incrementata cu unu, iar noua valoare este rezultatul expresiei. -- var Variabila este decrementata cu unu, iar noua valoare este rezultatul expresiei. var ++ Rezultatul expresiei este valoarea variabilei i apoi variabila este incrementata cu unu. var -- Rezultatul expresiei este valoarea variabilei i apoi variabila este decrementata cu unu. expr + expr Rezultatul expresiei este suma celor doua expresii. expr - expr Rezultatul expresiei este diferena dintre cele doua expresii. expr * expr Rezultatul expresiei este produsul celor doua expresii. expr / expr Rezultatul expresiei este coeficientul celor doua expresii. Scala rezultatului este valoarea variabilei scale. expr % expr Rezultatul expresiei este ,,restul" i este calculat in felul urmator. Pentru a calcula a%b, mai intai a/b este calculat la cifrele scale. Acest rezultat este utilizat pentru a calcula a-(a/b)*b la scala maximului dintre scale+scale(b) i scale(a). Daca scale este definita la zero i ambele expresii sunt numere intregi, aceasta expresie este funcia de rest intreg. expr ^ expr Rezultatul expresiei este valoarea primei expresii ridicata la a doua. A doua expresie trebuie sa fie un numar intreg; (daca a doua expresie nu este un numar intreg, este generat un avertisment i expresia este trunchiata pentru a obine o valoare intreaga). Scala rezultatului este scale daca exponentul este negativ. Daca exponentul este pozitiv, scala rezultatului este minimul dintre scala primei expresii inmulit cu valoarea exponentului i maximul dintre scale i scala primei expresii; (dde exemplu: scale(a^b) = min(scale(a)*b, max( scale, scale(a)))). Trebuie remarcat faptul ca expr^0 va returna intotdeauna valoarea 1. ( expr ) Aceasta modifica precedena standard pentru a fora evaluarea expresiei. var = expr Variabilei i se atribuie valoarea expresiei. var = expr Aceasta este echivalenta cu ,,var = var expr", cu excepia faptului ca partea ,,var" este evaluata o singura data. Acest lucru poate face o diferena daca ,,var" este o matrice. Expresiile relaionale sunt un tip special de expresie care evalueaza intotdeauna la 0 sau 1, 0 daca relaia este falsa i 1 daca relaia este adevarata. Acestea pot aparea in orice expresie valida; (bc POSIX impune ca expresiile relaionale sa fie utilizate numai in declaraiile if, while i for i ca numai un test relaional sa poata fi efectuat in acestea). Operatorii relaionali sunt expr1 < expr2 Rezultatul este 1 daca expr1 este strict mai mica decat expr2. expr1 <= expr2 Rezultatul este 1 daca expr1 este mai mica sau egala cu expr2. expr1 > expr2 Rezultatul este 1 daca expr1 este strict mai mare decat expr2. expr1 >= expr2 Rezultatul este 1 daca expr1 este mai mare sau egala cu expr2. expr1 == expr2 Rezultatul este 1 daca expr1 este egala cu expr2. expr1 != expr2 Rezultatul este 1 daca expr1 nu este egala cu expr2. Operaiile booleene sunt, de asemenea, valabile. (POSIX bc NU are operaii booleene). Rezultatul tuturor operaiilor booleene sunt 0 i 1 (pentru fals i adevarat) ca in expresiile relaionale. Operatorii booleeni sunt: !expr Rezultatul este 1 daca expr este 0. expr && expr Rezultatul este 1 daca ambele expresii sunt diferite de zero. expr || expr Rezultatul este 1 daca oricare dintre expresii este diferita de zero. Precedena expresiilor este dupa cum urmeaza: (de la cea mai mica la cea mai mare) operator ||, asociativ la stanga operator &&, asociativ la stanga operator !, neasociativ operatori relaionali, asociativi la stanga operator de atribuire, asociativ la dreapta operatori + i -, asociativ la stanga operatori *, / i %, asociativ la stanga operator ^, asociativ la dreapta operator unar -, neasociativ operatori ++ i --, neasociativi Aceasta precedena a fost aleasa astfel incat programele bc conforme cu POSIX sa ruleze corect. Acest lucru va face ca utilizarea operatorilor logici i relaionali sa aiba un comportament neobinuit atunci cand sunt utilizai cu expresii de atribuire. Luai in considerare expresia: a = 3 < 5 Majoritatea programatorilor C ar presupune ca acest lucru ar atribui rezultatul ,,3 < 5" (valoarea 1) variabilei ,,a". Ceea ce face acest lucru in bc este sa atribuie valoarea 3 variabilei ,,a" i apoi sa compare 3 cu 5. Cel mai bine este sa folosii paranteze atunci cand utilizai operatorii relaionali i logici cu operatorii de atribuire. Mai exista cateva expresii speciale care sunt furnizate in bc. Acestea au de-a face cu funcii definite de utilizator i funcii standard. Toate apar ca ,,nume(parametri)". Consultai seciunea privind funciile, pentru funciile definite de utilizator. Funciile standard sunt: length ( expresie ) Valoarea funciei length este numarul de cifre semnificative din expresie. read ( ) Funcia read (o extensie) va citi un numar de la intrarea standard, indiferent de locul in care apare funcia. Atenie, acest lucru poate cauza probleme cu amestecul de date i program la intrarea standard. Cea mai buna utilizare a acestei funcii este intr-un program scris anterior care are nevoie de intrare de la utilizator, dar nu permite niciodata introducerea codului de program de la utilizator. Valoarea funciei read este numarul citit de la intrarea standard folosind valoarea curenta a variabilei ibase pentru baza de conversie. scale ( expresie ) Valoarea funciei scale este numarul de cifre dupa punctul zecimal din expresie. sqrt ( expresie ) Valoarea funciei sqrt este radacina patrata a expresiei. Daca expresia este negativa, este generata o eroare in timpul execuiei. INSTRUCIUNI Instruciunile (ca in majoritatea limbajelor algebrice) asigura secvena de evaluare a expresiilor. In bc instruciunile sunt executate ,,de indata ce este posibil". Execuia are loc atunci cand este intalnita o linie noua i exista una sau mai multe instruciuni complete. Datorita acestei execuii imediate, liniile noi sunt foarte importante in bc. De fapt, atat punctul i virgula, cat i linia noua sunt utilizate ca separatoare de instruciuni. O linie noua plasata necorespunzator va cauza o eroare de sintaxa. Deoarece liniile noi sunt separatoare de instruciuni, este posibil sa se ascunda o linie noua prin utilizarea caracterului de bara oblica inversa. Secvena ,,\", unde este linia noua, apare pentru bc ca spaiu alb in loc de o linie noua. O lista de instruciuni este o serie de instruciuni separate prin punct i virgula i linii noi. Urmatoarea este o lista de instruciuni bc i ce fac acestea: (Lucrurile incluse in paranteze ([]) sunt pari opionale ale instruciunii). expresie Aceasta instruciune face unul din doua lucruri. Daca expresia incepe cu ,, ...", aceasta este considerata a fi o instruciune de atribuire. Daca expresia nu este o instruciune de atribuire, expresia este evaluata i imprimata la ieire. Dupa imprimarea numarului, este imprimata o linie noua. De exemplu, ,,a=1" este o instruciune de atribuire, iar ,,(a=1)" este o expresie care are o atribuire incorporata. Toate numerele care sunt imprimate sunt imprimate in baza specificata de variabila obase. Valorile valide pentru obase sunt de la 2 pana la BC_BASE_MAX; (ase vedea seciunea LIMITE.) Pentru bazele de la 2 la 16, se utilizeaza metoda obinuita de scriere a numerelor. Pentru baze mai mari de 16, bc utilizeaza o metoda de imprimare a cifrelor cu mai multe caractere, in care fiecare cifra de baza superioara este imprimata ca un numar de baza 10. Cifrele cu mai multe caractere sunt separate prin spaii. Fiecare cifra conine numarul de caractere necesare pentru a reprezenta valoarea in baza zece a ,,obase-1". Deoarece numerele sunt de o precizie arbitrara, este posibil ca unele numere sa nu poata fi imprimate pe o singura linie de ieire. Aceste numere lungi vor fi imparite pe linii folosind ,,\" ca ultim caracter pe o linie. Numarul maxim de caractere imprimate pe linie este de 70. Datorita naturii interactive a bc, imprimarea unui numar are ca efect secundar atribuirea valorii imprimate variabilei speciale last. Acest lucru permite utilizatorului sa recupereze ultima valoare imprimata fara a fi nevoit sa rescrie expresia care a imprimat numarul. Atribuirea la last este valabila i va suprascrie ultima valoare imprimata cu valoarea atribuita. Valoarea nou atribuita va ramane pana la imprimarea urmatorului numar sau pana la atribuirea unei alte valori la last; (unele instalaii pot permite utilizarea unui singur punct (.) care nu face parte dintr-un numar ca notaie scurta pentru last). ir irul este imprimat la ieire. irurile incep cu un caracter de ghilimele duble i conin toate caracterele pana la urmatorul caracter de ghilimele duble. Toate caracterele sunt luate literal, inclusiv orice linie noua. Dupa ir nu se imprima niciun caracter de linie noua. print lista Instruciunea print (o extensie) ofera o alta metoda de ieire. ,,Lista" este o lista de iruri de caractere i expresii separate prin virgule. Fiecare ir sau expresie este imprimata in ordinea din lista. Nu se imprima nicio linie noua de incheiere. Expresiile sunt evaluate, iar valoarea lor este imprimata i atribuita variabilei last. irurile de caractere din instruciunea print sunt imprimate la ieire i pot conine caractere speciale. Caracterele speciale incep cu caracterul de bara oblica inversa (\). Caracterele speciale recunoscute de bc sunt ,,a" (alerta sau clopoel), ,,b" (backspace), ,,f" (salt de pagina), ,,n" (linie noua), ,,r" (retur de carucior), ,,q" (ghilimele duble), ,,t" (tabulator) i ,,\" (bara oblica inversa). Orice alt caracter care urmeaza barei inverse va fi ignorat. { lista_instruciuni } Aceasta este instruciunea compusa. Aceasta permite gruparea mai multor instruciuni pentru execuie. if ( expresie ) instruciune1 [else instruciune2] Instruciunea if evalueaza expresia i executa instruciunea1 sau instruciunea2 in funcie de valoarea expresiei. Daca expresia este diferita de zero, se executa instruciunea1. Daca instruciunea2 este prezenta i valoarea expresiei este 0, atunci instruciunea2 este executata; (clauza else este o extensie). while ( expresie ) instruciune Instruciunea while va executa instruciunea in timp ce expresia este diferita de zero. Aceasta evalueaza expresia inainte de fiecare execuie a instruciunii. Incheierea buclei este cauzata de o valoare zero a expresiei sau de executarea unei instruciuni break. for ( expresie1] ; [expresie2] ; [expresie3] ) instruciune Instruciunea for controleaza executarea repetata a instruciunii. Expresia1 este evaluata inainte de bucla. Expresia2 este evaluata inainte de fiecare execuie a instruciunii. Daca este diferita de zero, instruciunea este evaluata. Daca este zero, bucla este terminata. Dupa fiecare execuie a instruciunii, expresia3 este evaluata inainte de reevaluarea expresiei2. Daca expresia1 sau expresia3 lipsesc, nu se evalueaza nimic in momentul in care acestea ar fi evaluate. Daca expresia2 lipsete, este la fel ca i inlocuirea expresiei2 cu valoarea 1; (expresiile opionale sunt o extensie, POSIX bc necesita toate cele trei expresii). Urmatorul este codul echivalent pentru instruciunea for: expresie1; while (expresie2) { declaraie expresie3; } break Aceasta instruciune determina o ieire forata din cea mai recenta instruciune while sau for care o include. continue Instruciunea continue (o extensie) face ca cea mai recenta instruciune for sa inceapa urmatoarea iteraie. halt Instruciunea halt (o extensie) este o instruciune executata care determina procesorul bc sa se opreasca numai atunci cand este executata. De exemplu, ,,if (0 == 1) halt" nu va determina terminarea bc deoarece instruciunea halt nu este executata. return Returneaza valoarea 0 de la o funcie; (consultai seciunea privind funciile). return ( expresie ) Returneaza valoarea expresiei dintr-o funcie; (consultai seciunea privind funciile). Ca extensie, parantezele nu sunt necesare. PSEUDO INSTRUCIUNI Aceste instruciuni nu sunt instruciuni in sensul tradiional. Ele nu sunt instruciuni executate. Funcia lor este indeplinita la momentul ,,compilarii". limits Afieaza limitele locale impuse de versiunea locala a bc. Aceasta este o extensie. quit Atunci cand instruciunea quit este citita, procesorul bc se termina, indiferent unde se gasete instruciunea quit. De exemplu, ,,if (0 == 1) quit" va determina terminarea procesorului bc. warranty Afieaza o notificare de garanie mai lunga. Aceasta este o extensie. FUNCII Funciile ofera o metoda de definire a unui calcul care poate fi executat ulterior. Funciile din bc calculeaza intotdeauna o valoare i o returneaza apelantului. Definiiile funciilor sunt ,,dinamice" in sensul ca o funcie este nedefinita pana cand o definiie este intalnita in intrare. Acea definiie este apoi utilizata pana cand este intalnita o alta funcie de definiie pentru acelai nume. Noua definiie inlocuiete atunci vechea definiie. O funcie este definita dupa cum urmeaza: define nume( parametri ) { linie noua lista_auto lista_de_instruciuni } Un apel de funcie este doar o expresie de forma ,,nume(parametri)". Parametrii sunt numere sau matrici (o extensie). In definiia funciei, zero sau mai muli parametri sunt definii prin enumerarea numelor lor separate prin virgula. Toi parametrii sunt parametrii de apel prin valoare. Matricele sunt specificate in definiia parametrilor prin notaia ,,nume[]". In apelul funciei, parametrii efectivi sunt expresii complete pentru parametrii numerici. Pentru pasarea matricelor se utilizeaza aceeai notaie ca i pentru definirea parametrilor matricelor. Matricea numita este pasata prin valoare catre funcie. Deoarece definiiile funciilor sunt dinamice, numarul i tipul parametrilor sunt verificate atunci cand se apeleaza o funcie. Orice neconcordana in ceea ce privete numarul sau tipurile de parametri va provoca o eroare in timpul execuiei. O eroare de execuie va aparea i in cazul apelarii unei funcii nedefinite. auto_list este o lista opionala de variabile care sunt pentru utilizare ,,locala". Sintaxa listei auto (daca este prezenta) este ,,auto nume, ... ;". (Punctul i virgula este opional.) Fiecare nume este numele unei variabile auto. Matricele pot fi specificate prin utilizarea aceleiai notaii ca in cazul parametrilor. Aceste variabile au valorile lor plasate pe o stiva la inceputul funciei. Variabilele sunt apoi iniializate la zero i utilizate pe parcursul execuiei funciei. La ieirea din funcie, aceste variabile sunt scoase, astfel incat valoarea iniiala (la momentul apelului funciei) a acestor variabile sa fie restaurata. Parametrii sunt de fapt variabile automate care sunt iniializate la o valoare furnizata in apelul funciei. Variabilele automate sunt diferite de variabilele locale tradiionale deoarece, daca funcia A apeleaza funcia B, B poate accesa variabilele automate ale funciei A folosind doar acelai nume, cu excepia cazului in care funcia B le-a numit variabile automate. Datorita faptului ca variabilele automate i parametrii sunt plasai pe o stiva, bc accepta funcii recursive. Corpul funciei este o lista de instruciuni bc. Din nou, instruciunile sunt separate prin punct i virgula sau linii noi. Instruciunile return determina terminarea unei funcii i returnarea unei valori. Exista doua versiuni ale instruciunii return. Prima forma, ,,return", returneaza valoarea 0 la expresia apelanta. A doua forma, ,,return ( expresie )", calculeaza valoarea expresiei i returneaza aceasta valoare expresiei apelante. Exista un ,,return (0)" implicit la sfaritul fiecarei funcii. Acest lucru permite unei funcii sa se incheie i sa returneze 0 fara o instruciune de returnare explicita. Funciile modifica, de asemenea, utilizarea variabilei ibase. Toate constantele din corpul funciei vor fi convertite folosind valoarea lui ibase la momentul apelului funciei. Modificarile lui ibase vor fi ignorate in timpul executarii funciei, cu excepia funciei standard read, care va utiliza intotdeauna valoarea curenta a lui ibase pentru conversia numerelor. Funciilor le-au fost adaugate mai multe extensii. In primul rand, formatul definiiei a fost uor relaxat. Standardul cere ca acolada de deschidere sa fie pe aceeai linie cu cuvantul-cheie define i toate celelalte pari trebuie sa fie pe liniile urmatoare. Aceasta versiune a bc va permite orice numar de linii noi inainte i dupa acolada de deschidere a funciei. De exemplu, urmatoarele definiii sunt valabile. define d (n) { return (2*n); } define d (n) { return (2*n); } Funciile pot fi definite ca void. O funcie vida nu returneaza nicio valoare i, prin urmare, nu poate fi utilizata in niciun loc care necesita o valoare. O funcie vida nu produce niciun rezultat atunci cand este apelata singura pe o linie de intrare. Cuvantul cheie void este plasat intre cuvantul cheie define i numele funciei. De exemplu, luai in considerare urmatoarea sesiune. define py (y) { print "--->", y, "<---", "\n"; } define void px (x) { print "--->", x, "<---", "\n"; } py(1) --->1<--- 0 px(1) --->1<--- Din moment ce py nu este o funcie nula (void), apelul la py(1) imprima rezultatul dorit i apoi imprima o a doua linie care este valoarea funciei. Deoarece valoarea unei funcii care nu primete o instruciune de revenire explicita este zero, se imprima zero. Pentru px(1), nu se imprima niciun zero deoarece funcia este o funcie nula. De asemenea, a fost adaugat apelul prin variabila pentru matrice. Pentru a declara o matrice cu apel prin variabila, declaraia parametrului matricei in definiia funciei arata ca ,,*nume[]". Apelul la funcie ramane acelai ca in cazul apelului prin valoare a matricelor. BIBLIOTECA DE MATEMATICA Daca bc este invocat cu opiunea -l, o biblioteca de matematica este preincarcata, iar scala implicita este fixata la 20. Funciile matematice ii vor calcula rezultatele la scala stabilita in momentul apelarii lor. Biblioteca de matematica definete urmatoarele funcii: s (x) Sinusul lui x, x este exprimat in radiani. c (x) Cosinusul lui x, x este exprimat in radiani. a (x) Arctangenta lui x, arctangenta returneaza radiani. l (x) Logaritmul natural al lui x. e (x) The exponential function of raising e to the value x. j (n,x) Funcia Bessel de ordin intreg n a lui x. EXEMPLE In /bin/sh, urmatorul text va atribui valoarea ,,pi" variabilei shell pi. pi=$(echo "scale=10; 4*a(1)" | bc -l) The following is the definition of the exponential function used in the math library. This function is written in POSIX bc. scale = 20 /* Folosete faptul ca e^x = (e^(x/2))^2 Cand x este suficient de mic, se folosete seria: e^x = 1 + x + x^2/2! + x^3/3! + ... */ define e(x) { auto a, d, e, f, i, m, v, z /* Verifica semnul lui x. */ if (x<0) { m = 1 x = -x } /* Precondiie x. */ z = scale; scale = 4 + z + .44*x; while (x > 1) { f += 1; x /= 2; } /* Iniializeaza variabilele. */ 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 } } In continuare este prezentat codul care utilizeaza caracteristicile extinse ale bc pentru a implementa un program simplu de calculare a soldurilor carnetului de cecuri. Acest program este cel mai bine sa fie pastrat intr-un fiier pentru a putea fi utilizat de mai multe ori fara a fi nevoie sa il rescriei la fiecare utilizare. scale=2 print ,,\nProgramul registrului de balane!\n" print ,, inei minte, depozitele sunt tranzacii negative.\n" print ,, Ieire printr-o tranzacie 0.\n\n" print "Soldul iniial? "; bal = read() bal /= 1 print "\n" while (1) { "current balance = "; bal "transaction? "; trans = read() if (trans == 0) break; bal -= trans bal /= 1 } quit Urmatoarea este definiia funciei factoriale recursive. define f (x) { if (x <= 1) return (1); return (f(x-1) * x); } OPIUNI PENTRU READLINE I LIBEDIT bc GNU poate fi compilat (prin intermediul unei opiuni configure) pentru a utiliza biblioteca editorului de intrare GNU readline sau biblioteca BSD libedit. Acest lucru permite utilizatorului sa editeze liniile inainte de a le trimite la bc. De asemenea, permite un istoric al liniilor tastate anterior. Cand aceasta opiune este selectata, bc mai are o variabila speciala. Aceasta variabila speciala, history este numarul de linii de istoric reinute. Pentru readline, o valoare de -1 inseamna ca se pastreaza un numar nelimitat de linii de istoric. Stabilirea valorii history la un numar pozitiv limiteaza numarul de linii de istoric la numarul dat. Valoarea 0 dezactiveaza funcia de istoric. Valoarea implicita este 100. Pentru mai multe informaii, citii manualele de utilizare pentru bibliotecile GNU readline, history i BSD libedit. Nu se pot activa in acelai timp readline i libedit. DIFERENE Aceasta versiune a bc a fost implementata pornind de la proiectul POSIX P1003.2/D11 i conine mai multe diferene i extensii in raport cu proiectul i implementarile tradiionale. Aceasta nu este implementata in mod tradiional folosind dc(1). Aceasta versiune este un proces unic care analizeaza i executa o traducere a codului de octei al programului. Exista o opiune ,,nedocumentata" (-c) care face ca programul sa trimita codul de octei la ieirea standard in loc sa il execute. Aceasta a fost utilizata in principal pentru depanarea analizorului i pregatirea bibliotecii de matematica. O sursa majora de diferene este reprezentata de extensii, atunci cand o caracteristica este extinsa pentru a adauga mai multe funcionalitai i de adaugiri, atunci cand sunt adaugate noi caracteristici. Urmatoarea este lista de diferene i extensii. variabila de mediu LANG Aceasta versiune nu este conforma cu standardul POSIX in ceea ce privete prelucrarea variabilei de mediu LANG i a tuturor variabilelor de mediu care incep cu LC_. nume bc tradiional i POSIX au nume cu o singura litera pentru funcii, variabile i matrici. Acestea au fost extinse pentru a fi nume cu mai multe caractere care incep cu o litera i pot conine litere, numere i caracterul de subliniere. iruri irurile nu au voie sa conina caractere NUL. POSIX spune ca toate caracterele trebuie sa fie incluse in iruri. last bc POSIX nu are o variabila last. Unele implementari ale bc utilizeaza punctul (.) intr-un mod similar. comparaii bc POSIX permite comparaiile numai in instruciunea if, instruciunea while i a doua expresie a instruciunii for. De asemenea, numai o operaie relaionala este permisa in fiecare dintre aceste instruciuni. instruciunea if, clauza else bc POSIX nu are o clauza else. instruciunea for bc POSIX impune ca toate expresiile sa fie prezente in instruciunea for. &&, ||, ! bc POSIX nu are operatori logici. funcia read bc POSIX nu are o funcie de citire. instruciunea print bc POSIX nu are o instruciune print . instruciunea continue bc POSIX nu are o instruciune continue. instruciunea return bc POSIX necesita paranteze in jurul expresiei return. parametri de matrice bc POSIX nu accepta (in prezent) parametrii matricei in intregime. Gramatica POSIX permite utilizarea matricelor in definiiile funciilor, dar nu ofera o metoda de a specifica o matrice ca parametru real; (aceasta este, cel mai probabil, o omisiune a gramaticii). Implementarile tradiionale ale bc au doar parametrii de tip matrice cu apel prin valoare. formatul funciei bc POSIX impune ca paranteza de deschidere sa se afle pe aceeai linie cu cuvantul-cheie define, iar declaraia auto pe linia urmatoare. =+, =-, =*, =/, =%, =^ POSIX bc nu necesita definirea acestor operatori de atribuire ,,in stil vechi". Aceasta versiune poate permite aceste atribuiri ,,in stil vechi". Utilizai declaraia limits pentru a vedea daca versiunea instalata le accepta. Daca accepta operatorii de atribuire ,,in stil vechi", instruciunea ,,a =- 1" va decrementa a cu 1 in loc sa stabileasca a la valoarea -1. spaii in numere Alte implementari ale bc permit spaii in numere. De exemplu, ,,x=1 3" ar atribui valoarea 13 variabilei x. Aceeai afirmaie ar cauza o eroare de sintaxa in aceasta versiune a bc. erori i execuie Aceasta implementare difera de alte implementari in ceea ce privete codul care va fi executat atunci cand se gasesc erori de sintaxa i alte erori in program. Daca se gasete o eroare de sintaxa in definiia unei funcii, recuperarea erorilor incearca sa gaseasca inceputul unei instruciuni i sa continue analizarea funciei. Odata ce este gasita o eroare de sintaxa in funcie, funcia nu va mai putea fi apelata i devine nedefinita. Erorile de sintaxa din codul de execuie interactiv vor invalida blocul de execuie curent. Blocul de execuie este incheiat de un sfarit de linie care apare dupa o secvena completa de instruciuni. De exemplu, a = 1 b = 2 are doua blocuri de execuie i { a = 1 b = 2 } are un singur bloc de execuie. Orice eroare in timp de execuie va incheia execuia blocului de execuie curent. Un avertisment de timp de execuie nu va incheia blocul de execuie curent. intreruperi In timpul unei sesiuni interactive, semnalul SIGINT (generat de obicei de caracterul control-C din terminal) va determina intreruperea execuiei blocului de execuie curent. Se va afia o eroare ,,runtime" indicand funcia care a fost intrerupta. Dupa ce toate structurile de timp de execuie au fost curaate, va fi afiat un mesaj pentru a notifica utilizatorul ca bc este gata pentru mai multe intrari. Toate funciile definite anterior raman definite, iar valoarea tuturor variabilelor non-auto este valoarea din punctul de intrerupere. Toate variabilele automate i parametrii funciilor sunt eliminai in timpul procesului de curaare. In timpul unei sesiuni non-interactive, semnalul SIGINT va pune capat intregii execuii a bc. LIMITE Urmatoarele sunt limitele existente in prezent pentru acest procesor bc. Este posibil ca unele dintre ele sa fi fost modificate de o instalare. Utilizai declaraia limits pentru a vedea valorile actuale. BC_BASE_MAX Baza maxima de ieire este de cel puin 10^9. Baza maxima de intrare este 16. BC_DIM_MAX In prezent, aceasta este o limita arbitrara de 65535, aa cum este distribuita. Instalarea dvs. poate fi diferita. BC_SCALE_MAX Numarul de cifre dupa punctul zecimal este limitat la INT_MAX cifre. De asemenea, numarul de cifre inainte de punctul zecimal este limitat la INT_MAX cifre. BC_STRING_MAX Limita numarului de caractere dintr-un ir este INT_MAX caractere. exponent Valoarea exponentului in operaia de ridicare la putere (^) este limitata la LONG_MAX. nume de variabile Limita actuala a numarului de nume unice este de 32767 pentru fiecare dintre variabilele simple, matrici i funcii. VARIABILE DE MEDIU Urmatoarele variabile de mediu sunt prelucrate de bc: POSIXLY_CORRECT Aceasta este aceeai ca i opiunea -s. BC_ENV_ARGS Acesta este un alt mecanism pentru a obine argumente pentru bc. Formatul este acelai ca al argumentelor din linia de comanda. Aceste argumente sunt procesate primele, astfel incat orice fiiere listate in argumentele de mediu sunt procesate inaintea oricaror fiiere de argumente din linia de comanda. Acest lucru permite utilizatorului sa configureze opiuni i fiiere ,,standard" care sa fie procesate la fiecare invocare a bc. Fiierele din variabilele de mediu ar conine, de obicei, definiii de funcii pentru funciile pe care utilizatorul dorete sa le defineasca de fiecare data cand bc este rulat. BC_LINE_LENGTH Acesta trebuie sa fie un numar intreg care sa specifice numarul de caractere dintr-o linie de ieire pentru numere. Acesta include caracterele de bara oblica inversa i de linie noua pentru numerele lungi. Ca extensie, valoarea zero dezactiveaza funcia de linii multiple. Orice alta valoare a acestei variabile care este mai mica de 3 stabilete lungimea liniei la 70. DIAGNOSTICARE Daca un fiier din linia de comanda nu poate fi deschis, bc va raporta ca fiierul nu este disponibil i se va incheia. De asemenea, exista diagnostice de compilare i de execuie care ar trebui sa se explice de la sine. ERORI Recuperarea erorilor nu este inca foarte buna. Trimitei rapoartele de erori prin pota electronica la adresa bug-bc@gnu.org. Asigurai-va ca includei cuvantul ,,bc" undeva in campul ,,Subiect:". AUTOR Philip A. Nelson philnelson@acm.org MULUMIRI Autorul dorete sa ii mulumeasca lui Steve Sommars (Steve.Sommars@att.com) pentru ajutorul sau extins in testarea implementarii. Au fost oferite multe sugestii excelente. Acesta este un produs mult mai bun datorita implicarii sale. TRADUCERE Traducerea in limba romana a acestui manual a fost facuta de Remus- Gabriel Chelu Aceasta traducere este documentaie gratuita; citii Licena publica generala GNU Versiunea 3 sau o versiune ulterioara cu privire la condiii privind drepturile de autor. NU se asuma NICIO RESPONSABILITATE. Daca gasii erori in traducerea acestui manual, va rugam sa trimitei un e-mail la . Proiectul GNU 5 ianuarie 2025 bc(1)