Scroll to navigation

bc(1) General Commands Manual bc(1)

NUME

bc - un limbaj de calcul cu precizie arbitrară

SINTAXĂ

bc [ -hlwsqv ] [opțiuni-lungi] [ fișier ... ]

DESCRIERE

bc este un limbaj care acceptă numere cu precizie arbitrară cu execuție interactivă a instrucțiunilor. Există unele asemănări în sintaxă cu limbajul de programare C. O bibliotecă de matematică standard este disponibilă prin opțiune de linie de comandă. Dacă se solicită, biblioteca de matematică este definită înainte de procesarea oricăror fișiere. bc începe prin procesarea codului din toate fișierele enumerate în linia de comandă, în ordinea enumerată. După ce toate fișierele au fost procesate, bc citește de la intrarea standard. Tot codul este executat pe măsură ce este citit; (dacă un fișier conține o comandă de oprire a procesorului, bc nu va citi niciodată de la intrarea standard).

Această versiune a bc conține mai multe extensii care depășesc implementările bc tradiționale și proiectul de standard POSIX. Opțiunile din linia de comandă pot face ca aceste extensii să afișeze un avertisment sau să fie respinse. Acest document descrie limbajul acceptat de acest procesor. Extensiile vor fi identificate ca atare.

OPȚIUNI

Afișează modul de utilizare și iese.
Forțează modul interactiv.
Definește biblioteca matematică standard.
Furnizează avertismente pentru extensiile la POSIX bc.
Procesează exact în limbajul POSIX bc.
Nu afișează mesajul normal de bun venit în GNU bc.
Afișează numărul versiunii și drepturile de autor și iese.

NUMERE

Cel mai de bază element în bc este numărul. Numerele sunt numere cu precizie arbitrară. Această precizie este atât în partea întreagă, cât și în partea fracționară. Toate numerele sunt reprezentate intern în zecimal și toate calculele sunt efectuate în zecimal; (această versiune trunchiază rezultatele operațiilor de împărțire și multiplicare). Există două atribute ale numerelor, lungimea și scala. Lungimea este numărul total de cifre zecimale utilizate de bc pentru a reprezenta un număr, iar scala este numărul total de cifre zecimale după punctul zecimal. De exemplu:


.000001 are o lungime de 6 și o scală de 6.
1935.000 are o lungime de 7 și o scală de 3.

VARIABILE

Numerele sunt stocate în două tipuri de variabile, variabile simple și matrice. Atât variabilele simple, cât și variabilele matrice sunt denumite. Numele încep cu o literă urmată de orice număr de litere, cifre și liniuțe de subliniere. Toate literele trebuie să fie în minuscule. Numele alfanumerice complete sunt o extensie; în bc POSIX toate numele sunt formate dintr-o singură literă minusculă). Tipul de variabilă este clar în funcție de context, deoarece toate numele variabilelor de tip matrice vor fi urmate de paranteze drepte ([]).

Există patru variabile speciale, scale, ibase, obase, și last. scale definește modul în care unele operații utilizează cifrele după punctul zecimal. Valoarea implicită a lui scale este 0. ibase și obase definesc baza de conversie pentru numerele de intrare și ieșire. Valoarea implicită atât pentru intrare, cât și pentru ieșire este baza 10. last (o extensie) este o variabilă care are valoarea ultimului număr afișat. Acestea vor fi discutate mai detaliat acolo unde este cazul. Toate aceste variabile pot avea valori atribuite, precum și utilizate în expresii.

COMENTARII

Comentariile din bc încep cu caracterele /* și se termină cu caracterele */. Comentariile pot începe oriunde și apar ca un singur spațiu în textul de intrare; (acest lucru face ca comentariile să delimiteze alte elemente de intrare - de exemplu, un comentariu nu poate fi găsit în mijlocul unui nume de variabilă). Comentariile includ orice linii noi (sfârșit de linie) între începutul și sfârșitul comentariului.

Pentru a oferi suport pentru utilizarea scripturilor pentru bc, a fost adăugat un comentariu pe o singură linie ca extensie. Un comentariu pe o singură linie începe la un caracter # și continuă până la următorul capăt de linie. Caracterul de sfârșit de linie nu face parte din comentariu și este procesat în mod normal.

EXPRESII

Numerele sunt manipulate prin expresii și instrucțiuni. Deoarece limbajul a fost conceput pentru a fi interactiv, instrucțiunile și expresiile sunt executate cât mai curând posibil. Nu există un program „principal”. În schimb, codul este executat pe măsură ce este întâlnit; (funcțiile, discutate în detaliu mai târziu, sunt definite atunci când sunt întâlnite).

O expresie simplă este doar o constantă. bc convertește constantele în numere zecimale interne folosind baza de intrare curentă, specificată de variabila ibase.; (există o excepție în funcții). Valorile valide pentru ibase sunt de la 2 la 36; (bazele mai mari de 16 sunt o extensie). Atribuirea unei valori în afara acestui interval pentru ibase va avea ca rezultat o valoare de 2 sau 36. Numerele de intrare pot conține caracterele 0-9 și A-Z. - Notă: Acestea trebuie să fie în majuscule. Literele minuscule sunt nume de variabile. - Numerele cu o singură cifră au întotdeauna valoarea cifrei indiferent de valoarea lui ibase, (de exemplu, A = 10.) Pentru numerele cu mai multe cifre, bc schimbă toate cifrele de intrare mai mari sau egale cu ibase la valoarea ibase-1. Acest lucru face ca numărul ZZZ să fie întotdeauna cel mai mare număr de 3 cifre din baza de intrare.

Expresiile complete sunt similare cu multe alte limbaje de nivel înalt. Deoarece există un singur tip de număr, nu există reguli pentru amestecarea tipurilor. În schimb, există reguli privind scala expresiilor. Fiecare expresie are o scală. Aceasta este derivată din scala numerelor originale, operația efectuată și, în multe cazuri, valoarea variabilei scale. Valorile legale ale variabilei scale sunt de la 0 la numărul maxim reprezentabil de un număr întreg C.

În următoarele descrieri ale expresiilor permise, „expr” se referă la o expresie completă, iar „var” se referă la o variabilă simplă sau la o matrice. O variabilă simplă este doar o

nume
iar o variabilă matrice este specificată ca
nume[expr]
Cu excepția cazului în care se menționează în mod specific, scala rezultatului este scara maximă a expresiilor implicate.
Rezultatul este negația expresiei.
++ var
Variabila este incrementată cu unu, iar noua valoare este rezultatul expresiei.
Variabila este decrementată cu unu, iar noua valoare este rezultatul expresiei.
Rezultatul expresiei este valoarea variabilei și apoi variabila este incrementată cu unu.
Rezultatul expresiei este valoarea variabilei și apoi variabila este decrementată cu unu.
Rezultatul expresiei este suma celor două expresii.
Rezultatul expresiei este diferența dintre cele două expresii.
Rezultatul expresiei este produsul celor două expresii.
Rezultatul expresiei este coeficientul celor două expresii. Scala rezultatului este valoarea variabilei scale.
Rezultatul expresiei este „restul” și este calculat în felul următor. Pentru a calcula a%b, mai întâi 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). Dacă scale este definită la zero și ambele expresii sunt numere întregi, această expresie este funcția de rest întreg.
Rezultatul expresiei este valoarea primei expresii ridicată la a doua. A doua expresie trebuie să fie un număr întreg; (dacă a doua expresie nu este un număr întreg, este generat un avertisment și expresia este trunchiată pentru a obține o valoare întreagă). Scala rezultatului este scale dacă exponentul este negativ. Dacă exponentul este pozitiv, scala rezultatului este minimul dintre scala primei expresii înmulțit 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 că expr^0 va returna întotdeauna valoarea 1.
( expr )
Aceasta modifică precedența standard pentru a forța evaluarea expresiei.
Variabilei i se atribuie valoarea expresiei.
Aceasta este echivalentă cu „var = var <op> expr”, cu excepția faptului că partea „var” este evaluată o singură dată. Acest lucru poate face o diferență dacă „var” este o matrice.

Expresiile relaționale sunt un tip special de expresie care evaluează întotdeauna la 0 sau 1, 0 dacă relația este falsă și 1 dacă relația este adevărată. Acestea pot apărea în orice expresie permisă; (bc POSIX impune ca expresiile relaționale să fie utilizate numai în declarațiile if, while și for și ca numai un test relațional să poată fi efectuat în acestea). Operatorii relaționali sunt

Rezultatul este 1 dacă expr1 este strict mai mică decât expr2.
Rezultatul este 1 dacă expr1 este mai mică sau egală cu expr2.
Rezultatul este 1 dacă expr1 este strict mai mare decât expr2.
Rezultatul este 1 dacă expr1 este mai mare sau egală cu expr2.
Rezultatul este 1 dacă expr1 este egală cu expr2.
Rezultatul este 1 dacă expr1 nu este egală cu expr2.

Operațiile booleene sunt, de asemenea, valabile; (bc POSIX NU are operații booleene). Rezultatul tuturor operațiilor booleene sunt 0 și 1 (pentru fals (false) și adevărat (true)) ca în expresiile relaționale. Operatorii booleeni sunt:

!expr
Rezultatul este 1 dacă expr este 0.
Rezultatul este 1 dacă ambele expresii sunt diferite de zero.
Rezultatul este 1 dacă oricare dintre expresii este diferită de zero.

Precedența expresiilor este după cum urmează: (de la cea mai mică la cea mai mare)

operator ||, asociativ la stânga
operator &&, asociativ la stânga
operator !, neasociativ
operatori relaționali, asociativi la stânga
operator de atribuire, asociativ la dreapta
operatori + și -, asociativ la stânga
operatori *, / și %, asociativ la stânga
operator ^, asociativ la dreapta
operator unar -, neasociativ
operatori ++ și --, neasociativi

Această precedență a fost aleasă astfel încât programele bc conforme cu POSIX să ruleze corect. Acest lucru va face ca utilizarea operatorilor logici și relaționali să aibă un comportament neobișnuit atunci când sunt utilizați cu expresii de atribuire. Luați în considerare expresia:

a = 3 < 5

Majoritatea programatorilor C ar presupune că acest lucru ar atribui rezultatul „3 < 5” (valoarea 1) variabilei „a”. Ceea ce face acest lucru în bc este să atribuie valoarea 3 variabilei „a” și apoi să compare 3 cu 5. Cel mai bine este să folosiți paranteze atunci când utilizați operatorii relaționali și logici cu operatorii de atribuire.

Mai există câteva expresii speciale care sunt furnizate în bc. Acestea au de-a face cu funcții definite de utilizator și funcții standard. Toate apar ca „nume(parametri)”. Consultați secțiunea privind funcțiile, pentru funcțiile definite de utilizator. Funcțiile standard sunt:

Valoarea funcției length este numărul de cifre semnificative din expresie.
Funcția read (o extensie) va citi un număr de la intrarea standard, indiferent de locul în care apare funcția. Atenție, acest lucru poate cauza probleme cu amestecul de date și program la intrarea standard. Cea mai bună utilizare a acestei funcții este într-un program scris anterior care are nevoie de intrare de la utilizator, dar nu permite niciodată introducerea codului de program de la utilizator. Valoarea funcției read este numărul citit de la intrarea standard folosind valoarea curentă a variabilei ibase pentru baza de conversie.
Valoarea funcției scale este numărul de cifre după punctul zecimal din expresie.
Valoarea funcției sqrt este rădăcina pătrată a expresiei. Dacă expresia este negativă, este generată o eroare în timpul execuției.

INSTRUCȚIUNI

Instrucțiunile (ca în majoritatea limbajelor algebrice) asigură secvența de evaluare a expresiilor. În bc instrucțiunile sunt executate „de îndată ce este posibil”. Execuția are loc atunci când este întâlnită o linie nouă și există una sau mai multe instrucțiuni complete. Datorită acestei execuții imediate, liniile noi sunt foarte importante în bc. De fapt, atât punctul și virgula, cât și linia nouă sunt utilizate ca separatoare de instrucțiuni. O linie nouă plasată necorespunzător va cauza o eroare de sintaxă. Deoarece liniile noi sunt separatoare de instrucțiuni, este posibil să se ascundă o linie nouă prin utilizarea caracterului de bară oblică inversă. Secvența „\<nl>”, unde <nl> este linia nouă, apare pentru bc ca spațiu alb în loc de o linie nouă. O listă de instrucțiuni este o serie de instrucțiuni separate prin punct și virgulă și linii noi. Următoarea este o listă de instrucțiuni bc și ce fac acestea: (Lucrurile incluse în paranteze ([]) sunt părți opționale ale instrucțiunii).

Această instrucțiune face unul din două lucruri. Dacă expresia începe cu „<variable> <assignment> ...”, aceasta este considerată a fi o instrucțiune de atribuire. Dacă expresia nu este o instrucțiune de atribuire, expresia este evaluată și imprimată la ieșire. După imprimarea numărului, este imprimată o linie nouă. De exemplu, „a=1” este o instrucțiune de atribuire, iar „(a=1)” este o expresie care are o atribuire încorporată. Toate numerele care sunt imprimate sunt imprimate în baza specificată de variabila obase. Valorile valabile pentru obase sunt de la 2 până la BC_BASE_MAX; (ase vedea secțiunea LIMITE.) Pentru bazele de la 2 la 16, se utilizează metoda obișnuită de scriere a numerelor. Pentru baze mai mari de 16, bc utilizează o metodă de imprimare a cifrelor cu mai multe caractere, în care fiecare cifră de bază superioară este imprimată ca un număr de bază 10. Cifrele cu mai multe caractere sunt separate prin spații. Fiecare cifră conține numărul de caractere necesare pentru a reprezenta valoarea în bază zece a „obase-1”. Deoarece numerele sunt de o precizie arbitrară, este posibil ca unele numere să nu poată fi imprimate pe o singură linie de ieșire. Aceste numere lungi vor fi împărțite pe linii folosind „\” ca ultim caracter pe o linie. Numărul maxim de caractere imprimate pe linie este de 70. Datorită naturii interactive a bc, imprimarea unui număr are ca efect secundar atribuirea valorii imprimate variabilei speciale last. Acest lucru permite utilizatorului să recupereze ultima valoare imprimată fără a fi nevoit să rescrie expresia care a imprimat numărul. Atribuirea la last este valabilă și va suprascrie ultima valoare imprimată cu valoarea atribuită. Valoarea nou atribuită va rămâne până la imprimarea următorului număr sau până la atribuirea unei alte valori la last; (unele instalații pot permite utilizarea unui singur punct (.) care nu face parte dintr-un număr ca notație scurtă pentru last).
șir
Șirul este imprimat la ieșire. Șirurile încep cu un caracter de ghilimele duble și conțin toate caracterele până la următorul caracter de ghilimele duble. Toate caracterele sunt luate literal, inclusiv orice linie nouă. După șir nu se imprimă niciun caracter de linie nouă.
Instrucțiunea print (o extensie) oferă o altă metodă de ieșire. „Lista” este o listă de șiruri de caractere și expresii separate prin virgule. Fiecare șir sau expresie este imprimată în ordinea din listă. Nu se imprimă nicio linie nouă de încheiere. Expresiile sunt evaluate, iar valoarea lor este imprimată și atribuită variabilei last. Șirurile de caractere din instrucțiunea print sunt imprimate la ieșire și pot conține caractere speciale. Caracterele speciale încep cu caracterul de bară oblică inversă (\). Caracterele speciale recunoscute de bc sunt „a” (alertă sau clopoțel), „b” (backspace), „f” (salt de pagină), „n” (linie nouă), „r” (retur de cărucior), „q” (ghilimele duble), „t” (tabulator) și „\” (bară oblică inversă). Orice alt caracter care urmează barei inverse va fi ignorat.
{ listă_instrucțiuni }
Aceasta este instrucțiunea compusă. Aceasta permite gruparea mai multor instrucțiuni pentru execuție.
Instrucțiunea if evaluează expresia și execută instrucțiunea1 sau instrucțiunea2 în funcție de valoarea expresiei. Dacă expresia este diferită de zero, se execută instrucțiunea1. Dacă instrucțiunea2 este prezentă și valoarea expresiei este 0, atunci instrucțiunea2 este executată; (clauza else este o extensie).
Instrucțiunea while va executa instrucțiunea în timp ce expresia este diferită de zero. Aceasta evaluează expresia înainte de fiecare execuție a instrucțiunii. Încheierea buclei este cauzată de o valoare zero a expresiei sau de executarea unei instrucțiuni break.
Instrucțiunea for controlează executarea repetată a instrucțiunii. Expresia1 este evaluată înainte de buclă. Expresia2 este evaluată înainte de fiecare execuție a instrucțiunii. Dacă este diferită de zero, instrucțiunea este evaluată. Dacă este zero, bucla este terminată. După fiecare execuție a instrucțiunii, expresia3 este evaluată înainte de reevaluarea expresiei2. Dacă expresia1 sau expresia3 lipsesc, nu se evaluează nimic în momentul în care acestea ar fi evaluate. Dacă expresia2 lipsește, este la fel ca și înlocuirea expresiei2 cu valoarea 1; (expresiile opționale sunt o extensie, POSIX bc necesită toate cele trei expresii). Următorul este codul echivalent pentru instrucțiunea for:
expresie1;
while (expresie2) {

declarație
expresie3; }

Această instrucțiune determină o ieșire forțată din cea mai recentă instrucțiune while sau for care o include.
Instrucțiunea continue (o extensie) face ca cea mai recentă instrucțiune for să înceapă următoarea iterație.
Instrucțiunea halt (o extensie) este o instrucțiune executată care determină procesorul bc să se oprească numai atunci când este executată. De exemplu, „if (0 == 1) halt” nu va determina terminarea bc deoarece instrucțiunea halt nu este executată.
Returnează valoarea 0 de la o funcție; (consultați secțiunea privind funcțiile).
Returnează valoarea expresiei dintr-o funcție; (consultați secțiunea privind funcțiile). Ca extensie, parantezele nu sunt necesare.

PSEUDO INSTRUCȚIUNI

Aceste instrucțiuni nu sunt instrucțiuni în sensul tradițional. Ele nu sunt instrucțiuni executate. Funcția lor este îndeplinită la momentul „compilării”.

Afișează limitele locale impuse de versiunea locală a bc. Aceasta este o extensie.
Atunci când instrucțiunea quit este citită, procesorul bc se termină, indiferent unde se găsește instrucțiunea quit. De exemplu, „if (0 == 1) quit” va determina terminarea procesorului bc.
Afișează o notificare de garanție mai lungă. Aceasta este o extensie.

FUNCȚII

Funcțiile oferă o metodă de definire a unui calcul care poate fi executat ulterior. Funcțiile din bc calculează întotdeauna o valoare și o returnează apelantului. Definițiile funcțiilor sunt „dinamice” în sensul că o funcție este nedefinită până când o definiție este întâlnită în intrare. Acea definiție este apoi utilizată până când este întâlnită o altă funcție de definiție pentru același nume. Noua definiție înlocuiește atunci vechea definiție. O funcție este definită după cum urmează:

define nume( parametri ) { linie nouă     listă_auto listă_de_instrucțiuni }

Un apel de funcție este doar o expresie de forma „nume(parametri)”.

Parametrii sunt numere sau matrici (o extensie). În definiția funcției, zero sau mai mulți parametri sunt definiți prin enumerarea numelor lor separate prin virgulă. Toți parametrii sunt parametrii de apel prin valoare. Matricele sunt specificate în definiția parametrilor prin notația „nume[]”. În apelul funcției, parametrii efectivi sunt expresii complete pentru parametrii numerici. Pentru pasarea matricelor se utilizează aceeași notație ca și pentru definirea parametrilor matricelor. Matricea numită este pasată prin valoare către funcție. Deoarece definițiile funcțiilor sunt dinamice, numărul și tipul parametrilor sunt verificate atunci când se apelează o funcție. Orice neconcordanță în ceea ce privește numărul sau tipurile de parametri va provoca o eroare în timpul execuției. O eroare de execuție va apărea și în cazul apelării unei funcții nedefinite.

auto_list este o listă opțională de variabile care sunt pentru utilizare „locală”. Sintaxa listei auto (dacă este prezentă) este „auto nume, ... ;”. (Punctul și virgula este opțional.) Fiecare nume este numele unei variabile auto. Matricele pot fi specificate prin utilizarea aceleiași notații ca în cazul parametrilor. Aceste variabile au valorile lor plasate pe o stivă la începutul funcției. Variabilele sunt apoi inițializate la zero și utilizate pe parcursul execuției funcției. La ieșirea din funcție, aceste variabile sunt scoase, astfel încât valoarea inițială (la momentul apelului funcției) a acestor variabile să fie restaurată. Parametrii sunt de fapt variabile automate care sunt inițializate la o valoare furnizată în apelul funcției. Variabilele automate sunt diferite de variabilele locale tradiționale deoarece, dacă funcția A apelează funcția B, B poate accesa variabilele automate ale funcției A folosind doar același nume, cu excepția cazului în care funcția B le-a numit variabile automate. Datorită faptului că variabilele automate și parametrii sunt plasați pe o stivă, bc acceptă funcții recursive.

Corpul funcției este o listă de instrucțiuni bc. Din nou, instrucțiunile sunt separate prin punct și virgulă sau linii noi. Instrucțiunile return determină terminarea unei funcții și returnarea unei valori. Există două versiuni ale instrucțiunii return. Prima formă, „return”, returnează valoarea 0 la expresia apelantă. A doua formă, „return ( expresie )”, calculează valoarea expresiei și returnează această valoare expresiei apelante. Există un „return (0)” implicit la sfârșitul fiecărei funcții. Acest lucru permite unei funcții să se încheie și să returneze 0 fără o instrucțiune de returnare explicită.

Funcțiile modifică, de asemenea, utilizarea variabilei ibase. Toate constantele din corpul funcției vor fi convertite folosind valoarea lui ibase la momentul apelului funcției. Modificările lui ibase vor fi ignorate în timpul executării funcției, cu excepția funcției standard read, care va utiliza întotdeauna valoarea curentă a lui ibase pentru conversia numerelor.

Funcțiilor le-au fost adăugate mai multe extensii. În primul rând, formatul definiției a fost ușor relaxat. Standardul cere ca acolada de deschidere să fie pe aceeași linie cu cuvântul-cheie define și toate celelalte părți trebuie să fie pe liniile următoare. Această versiune a bc va permite orice număr de linii noi înainte și după acolada de deschidere a funcției. De exemplu, următoarele definiții sunt valabile.

 define d (n) { return (2*n); } define d (n)   { return (2*n); }

Funcțiile pot fi definite ca void. O funcție vidă nu returnează nicio valoare și, prin urmare, nu poate fi utilizată în niciun loc care necesită o valoare. O funcție vidă nu produce niciun rezultat atunci când este apelată singură pe o linie de intrare. Cuvântul cheie void este plasat între cuvântul cheie define și numele funcției. De exemplu, luați în considerare următoarea 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 funcție nulă (void), apelul la
  py(1) imprimă rezultatul dorit și apoi imprimă o a
  doua linie care este valoarea funcției. Deoarece valoarea unei
  funcții care nu primește o instrucțiune de revenire
  explicită este zero, se imprimă zero. Pentru px(1), nu se
  imprimă niciun zero deoarece funcția este o funcție
  nulă.

De asemenea, a fost adăugat apelul prin variabilă pentru matrice. Pentru a declara o matrice cu apel prin variabilă, declarația parametrului matricei în definiția funcției arată ca „*nume[]”. Apelul la funcție rămâne același ca în cazul apelului prin valoare a matricelor.

BIBLIOTECA DE MATEMATICĂ

Dacă bc este invocat cu opțiunea -l, o bibliotecă de matematică este preîncărcată, iar scala implicită este fixată la 20. Funcțiile matematice își vor calcula rezultatele la scala stabilită în momentul apelării lor. Biblioteca de matematică definește următoarele funcții:

Sinusul lui x, x este exprimat în radiani.
Cosinusul lui x, x este exprimat în radiani.
Arctangenta lui x, arctangenta returnează radiani.
Logaritmul natural al lui x.
The exponential function of raising e to the value x.
Funcția Bessel de ordin întreg n a lui x.

EXEMPLE

În /bin/sh, următorul 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
/* Folosește faptul că e^x = (e^(x/2))^2    Când x este suficient de mic, se folosește seria:      e^x = 1 + x + x^2/2! + x^3/3! + ... */
define e(x) {   auto  a, d, e, f, i, m, v, z
  /* Verifică semnul lui x. */   if (x<0) {     m = 1     x = -x   }
  /* Precondiție x. */   z = scale;   scale = 4 + z + .44*x;   while (x > 1) {     f += 1;     x /= 2;   }
  /* Inițializează 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   } }

În continuare este prezentat codul care utilizează caracteristicile extinse ale bc pentru a implementa un program simplu de calculare a soldurilor carnetului de cecuri. Acest program este cel mai bine să fie păstrat într-un fișier pentru a putea fi utilizat de mai multe ori fără a fi nevoie să îl rescrieți la fiecare utilizare.

 scale=2 print "\nProgramul registrului de balanțe!\n” print „ Țineți minte, depozitele sunt tranzacții negative.\n” print „ Ieșire printr-o tranzacție 0.\n\n"
print "Soldul inițial? "; bal = read() bal /= 1 print "\n" while (1) {   "current balance = "; bal   "transaction? "; trans = read()   if (trans == 0) break;   bal -= trans   bal /= 1 } quit

Următoarea este definiția funcției factoriale recursive.

 define f (x) {   if (x <= 1) return (1);   return (f(x-1) * x); }

OPȚIUNI PENTRU READLINE ȘI LIBEDIT

bc GNU poate fi compilat (prin intermediul unei opțiuni configure) pentru a utiliza biblioteca editorului de intrare GNU readline sau biblioteca BSD libedit. Acest lucru permite utilizatorului să editeze liniile înainte de a le trimite la bc. De asemenea, permite un istoric al liniilor tastate anterior. Când această opțiune este selectată, bc mai are o variabilă specială. Această variabilă specială, history este numărul de linii de istoric reținute. Pentru readline, o valoare de -1 înseamnă că se păstrează un număr nelimitat de linii de istoric. Stabilirea valorii history la un număr pozitiv limitează numărul de linii de istoric la numărul dat. Valoarea 0 dezactivează funcția de istoric. Valoarea implicită este 100. Pentru mai multe informații, citiți manualele de utilizare pentru bibliotecile GNU readline, history și BSD libedit. Nu se pot activa în același timp readline și libedit.

DIFERENȚE

Această versiune a bc a fost implementată pornind de la proiectul POSIX P1003.2/D11 și conține mai multe diferențe și extensii în raport cu proiectul și implementările tradiționale. Aceasta nu este implementată în mod tradițional folosind dc(1). Această versiune este un proces unic care analizează și execută o traducere a codului de octeți al programului. Există o opțiune „nedocumentată” (-c) care face ca programul să trimită codul de octeți la ieșirea standard în loc să îl execute. Aceasta a fost utilizată în principal pentru depanarea analizorului și pregătirea bibliotecii de matematică.

O sursă majoră de diferențe este reprezentată de extensii, atunci când o caracteristică este extinsă pentru a adăuga mai multe funcționalități și de adăugiri, atunci când sunt adăugate noi caracteristici. Următoarea este lista de diferențe și extensii.

Această versiune nu este conformă cu standardul POSIX în ceea ce privește prelucrarea variabilei de mediu LANG și a tuturor variabilelor de mediu care încep cu LC_.
bc tradițional și POSIX au nume cu o singură literă pentru funcții, variabile și matrici. Acestea au fost extinse pentru a fi nume cu mai multe caractere care încep cu o literă și pot conține litere, numere și caracterul de subliniere.
Șiruri
Șirurile nu au voie să conțină caractere NUL. POSIX spune că toate caracterele trebuie să fie incluse în șiruri.
bc POSIX nu are o variabilă last. Unele implementări ale bc utilizează punctul (.) într-un mod similar.
bc POSIX permite comparațiile numai în instrucțiunea if, instrucțiunea while și a doua expresie a instrucțiunii for. De asemenea, numai o operație relațională este permisă în fiecare dintre aceste instrucțiuni.
bc POSIX nu are o clauză else.
bc POSIX impune ca toate expresiile să fie prezente în instrucțiunea for.
&&, ||, !
bc POSIX nu are operatori logici.
bc POSIX nu are o funcție de citire.
bc POSIX nu are o instrucțiune print .
bc POSIX nu are o instrucțiune continue.
bc POSIX necesită paranteze în jurul expresiei return.
bc POSIX nu acceptă (în prezent) parametrii matricei în întregime. Gramatica POSIX permite utilizarea matricelor în definițiile funcțiilor, dar nu oferă o metodă de a specifica o matrice ca parametru real; (aceasta este, cel mai probabil, o omisiune a gramaticii). Implementările tradiționale ale bc au doar parametrii de tip matrice cu apel prin valoare.
bc POSIX impune ca paranteza de deschidere să se afle pe aceeași linie cu cuvântul-cheie define, iar declarația auto pe linia următoare.
=+, =-, =*, =/, =%, =^
POSIX bc nu necesită definirea acestor operatori de atribuire „în stil vechi”. Această versiune poate permite aceste atribuiri „în stil vechi”. Utilizați declarația limits pentru a vedea dacă versiunea instalată le acceptă. Dacă acceptă operatorii de atribuire „în stil vechi”, instrucțiunea „a =- 1” va decrementa a cu 1 în loc să stabilească a la valoarea -1.
Alte implementări ale bc permit spații în numere. De exemplu, „x=1 3” ar atribui valoarea 13 variabilei x. Aceeași afirmație ar cauza o eroare de sintaxă în această versiune a bc.
Această implementare diferă de alte implementări în ceea ce privește codul care va fi executat atunci când se găsesc erori de sintaxă și alte erori în program. Dacă se găsește o eroare de sintaxă în definiția unei funcții, recuperarea erorilor încearcă să găsească începutul unei instrucțiuni și să continue analizarea funcției. Odată ce este găsită o eroare de sintaxă în funcție, funcția nu va mai putea fi apelată și devine nedefinită. Erorile de sintaxă din codul de execuție interactiv vor invalida blocul de execuție curent. Blocul de execuție este încheiat de un sfârșit de linie care apare după o secvență completă de instrucțiuni. De exemplu,
a = 1
b = 2

are două blocuri de execuție și
{ a = 1

b = 2 }

are un singur bloc de execuție. Orice eroare în timp de execuție va încheia execuția blocului de execuție curent. Un avertisment de timp de execuție nu va încheia blocul de execuție curent.

întreruperi
În timpul unei sesiuni interactive, semnalul SIGINT (generat de obicei de caracterul control-C din terminal) va determina întreruperea execuției blocului de execuție curent. Se va afișa o eroare „runtime” indicând funcția care a fost întreruptă. După ce toate structurile de timp de execuție au fost curățate, va fi afișat un mesaj pentru a notifica utilizatorul că bc este gata pentru mai multe intrări. Toate funcțiile definite anterior rămân definite, iar valoarea tuturor variabilelor non-auto este valoarea din punctul de întrerupere. Toate variabilele automate și parametrii funcțiilor sunt eliminați în timpul procesului de curățare. În timpul unei sesiuni non-interactive, semnalul SIGINT va pune capăt întregii execuții a bc.

LIMITE

Următoarele sunt limitele existente în prezent pentru acest procesor bc. Este posibil ca unele dintre ele să fi fost modificate de o instalare. Utilizați declarația limits pentru a vedea valorile actuale.

Baza maximă de ieșire este stabilită în prezent la 999. Baza maximă de intrare este 16.
În prezent, aceasta este o limită arbitrară de 65535, așa cum este distribuită. Instalarea dvs. poate fi diferită.
Numărul de cifre după punctul zecimal este limitat la INT_MAX cifre. De asemenea, numărul de cifre înainte de punctul zecimal este limitat la INT_MAX cifre.
Limita numărului de caractere dintr-un șir este INT_MAX caractere.
Valoarea exponentului în operația de ridicare la putere (^) este limitată la LONG_MAX.
nume de variabile
Limita actuală a numărului de nume unice este de 32767 pentru fiecare dintre variabilele simple, matrici și funcții.

VARIABILE DE MEDIU

Următoarele variabile de mediu sunt prelucrate de bc:

Aceasta este aceeași ca și opțiunea -s.
Acesta este un alt mecanism pentru a obține argumente pentru bc. Formatul este același ca al argumentelor din linia de comandă. Aceste argumente sunt procesate primele, astfel încât orice fișiere listate în argumentele de mediu sunt procesate înaintea oricăror fișiere de argumente din linia de comandă. Acest lucru permite utilizatorului să configureze opțiuni și fișiere „standard” care să fie procesate la fiecare invocare a bc. Fișierele din variabilele de mediu ar conține, de obicei, definiții de funcții pentru funcțiile pe care utilizatorul dorește să le definească de fiecare dată când bc este rulat.
Acesta trebuie să fie un număr întreg care să specifice numărul de caractere dintr-o linie de ieșire pentru numere. Acesta include caracterele de bară oblică inversă și de linie nouă pentru numerele lungi. Ca extensie, valoarea zero dezactivează funcția de linii multiple. Orice altă valoare a acestei variabile care este mai mică de 3 stabilește lungimea liniei la 70.

DIAGNOSTICARE

Dacă un fișier din linia de comandă nu poate fi deschis, bc va raporta că fișierul nu este disponibil și se va încheia. De asemenea, există diagnostice de compilare și de execuție care ar trebui să se explice de la sine.

ERORI

Recuperarea erorilor nu este încă foarte bună.

Trimiteți rapoartele de erori prin poștă electronică la adresa bug-bc@gnu.org. Asigurați-vă că includeți cuvântul „bc” undeva în câmpul „Subiect:”.

AUTOR

Philip A. Nelson
philnelson@acm.org

MULȚUMIRI

Autorul dorește să îi mulțumească lui Steve Sommars (Steve.Sommars@att.com) pentru ajutorul său extins în testarea implementării. Au fost oferite multe sugestii excelente. Acesta este un produs mult mai bun datorită implicării sale.

TRADUCERE

Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.

11 iunie 2006 Proiectul GNU