Suprasolicitarea numerelor întregi

.

.

Manipularea suprasolicitării numerelor întregi în diverse limbaje de programare
Limbajul Întreg fără semn Întreg fără semn Întreg cu semn
Ada modul modulul tipului raise Constraint_Error
C/C++ modulo power of two comportament nedefinit
C# modulo power of 2 in unchecked context; System.OverflowException este ridicat în context verificat
Java N/A modulo puterea a 2
JavaScript toate numerele sunt duble-.precizie în virgulă flotantă, cu excepția noului BigInt
MATLAB Întregii construiți se saturează. Fix-numere întregi cu virgulă fixă configurabile pentru a înfășura sau satura
Python 2 N/A convert to long type (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A convert to bigNum
Simulink configurabil pentru a înfășura sau satura
Smalltalk N/A convert to LargeInteger
Swift Provoacă o eroare dacă nu se folosesc operatori speciali de depășire.

DetectionEdit

Implementarea UBSan de detectare a depășirilor în timp de execuție este disponibilă pentru compilatoarele C.

În Java 8, există metode supraîncărcate, de exemplu ca Math.addExact(int, int), care vor arunca ArithmeticException în caz de depășire.

Computer emergency response team (CERT) a dezvoltat modelul de numere întregi As-if Infinitely Ranged (AIR), un mecanism în mare parte automatizat pentru a elimina depășirea și trunchierea numerelor întregi în C/C++, folosind gestionarea erorilor în timpul execuției.

Editură de evitare

Prin alocarea de variabile cu tipuri de date suficient de mari pentru a conține toate valorile care pot fi eventual calculate și stocate în ele, este întotdeauna posibil să se evite depășirea. Chiar și atunci când spațiul disponibil sau tipurile de date fixe furnizate de un limbaj sau mediu de programare sunt prea limitate pentru a permite alocarea defensivă a variabilelor cu dimensiuni generoase, prin ordonarea atentă a operațiilor și verificarea prealabilă a operanzilor, este adesea posibil să se asigure a priori că rezultatul nu va fi niciodată mai mare decât poate fi stocat. Instrumentele de analiză statică, verificarea formală și tehnicile de proiectare prin contract pot fi utilizate pentru a se asigura cu mai multă încredere și robustețe că nu poate rezulta accidental o depășire de capacitate.

HandlingEdit

Dacă se anticipează că poate apărea o depășire de capacitate, atunci pot fi inserate teste în program pentru a detecta când se întâmplă sau este pe cale să se întâmple și pentru a face alte prelucrări pentru a o atenua. De exemplu, în cazul în care un rezultat important calculat în urma unei intrări a utilizatorului se supraîncarcă, programul se poate opri, poate respinge intrarea și poate solicita utilizatorului o altă intrare, în loc ca programul să continue cu intrarea invalidă supraîncărcată și, probabil, să funcționeze defectuos ca o consecință. Acest proces complet poate fi automatizat: este posibil să se sintetizeze automat un gestionar pentru o depășire de numere întregi, unde gestionarul este, de exemplu, o ieșire curată.

Unitățile centrale de calcul au, în general, o modalitate de a detecta acest lucru pentru a suporta adunarea numerelor mai mari decât dimensiunea registrului lor, folosind de obicei un bit de stare; tehnica se numește aritmetică de precizie multiplă.Astfel, este posibilă adunarea a două numere, fiecare cu o lățime de doi octeți, folosind doar o adunare de octeți în pași: mai întâi se adună octeții mici, apoi se adaugă octeții mari, dar dacă este necesar să se efectueze din octeții mici, aceasta reprezintă o depășire aritmetică a adunării de octeți și devine necesară detectarea și incrementarea sumei octeților mari.

Manipularea unei posibile depășiri a unui calcul poate prezenta uneori o alegere între efectuarea unei verificări înainte de calculul propriu-zis (pentru a determina dacă va avea loc sau nu depășirea) sau după acesta (pentru a lua în considerare dacă este posibil să se fi produs sau nu, pe baza valorii rezultate). Ar trebui să se dea dovadă de prudență față de cea din urmă alegere. În primul rând, deoarece s-ar putea să nu fie o metodă de detectare fiabilă (de exemplu, o adunare nu se poate încheia neapărat cu o valoare mai mică). În al doilea rând, pentru că, în unele cazuri, apariția depășirii în sine poate fi un comportament nedefinit. În limbajul de programare C, depășirea tipurilor de numere întregi fără semn are ca rezultat o supraîncărcare, însă depășirea tipurilor de numere întregi cu semn este un comportament nedefinit; în consecință, un compilator C este liber să presupună că programatorul s-a asigurat că depășirea cu semn nu poate avea loc și, prin urmare, poate optimiza în mod silențios orice verificare ulterioară calculului care implică verificarea rezultatului pentru a o detecta, fără a avertiza programatorul că acest lucru a fost făcut. Prin urmare, este recomandabil să se prefere întotdeauna să se implementeze verificările înainte de calcule și nu după ele.

Propagare explicităEdit

dacă o valoare este prea mare pentru a fi stocată, i se poate atribui o valoare specială care să indice faptul că a avut loc o depășire și apoi toate operațiile succesive să returneze această valoare de semnalizare. Astfel de valori sunt uneori denumite NaN, pentru „not a number” (nu este un număr). Acest lucru este util pentru ca problema să poată fi verificată o singură dată la sfârșitul unui calcul lung, mai degrabă decât după fiecare pas. Acest lucru este adesea suportat în hardware-ul cu virgulă mobilă numit FPU.

Suportul limbajelor de programareEdit

Limbajele de programare implementează diverse metode de atenuare împotriva unei depășiri accidentale: Ada, Seed7 (și anumite variante de limbaje funcționale), declanșează o condiție de excepție la depășire, în timp ce Python (începând cu versiunea 2.4) convertește fără probleme reprezentarea internă a numărului pentru a se potrivi cu creșterea acestuia, reprezentându-l în cele din urmă ca long – a cărui capacitate este limitată doar de memoria disponibilă.

În limbajele cu suport nativ pentru aritmetica de precizie arbitrară și siguranța tipurilor (cum ar fi Python, Smalltalk sau Common Lisp), numerele sunt promovate la o dimensiune mai mare în mod automat atunci când au loc depășiri, sau sunt lansate excepții (condiții semnalate) atunci când există o constrângere de interval. Prin urmare, utilizarea unor astfel de limbaje poate fi utilă pentru a atenua această problemă. Cu toate acestea, în unele astfel de limbaje, sunt încă posibile situații în care se poate produce o depășire de număr întreg. Un exemplu este optimizarea explicită a unui traseu de cod care este considerat de profiler ca fiind un gât de gâtuire. În cazul Common Lisp, acest lucru este posibil prin utilizarea unei declarații explicite pentru a nota tipul unei variabile la un cuvânt de dimensiunea mașinii (fixnum) și pentru a reduce nivelul de siguranță a tipului la zero pentru un anumit bloc de cod.

În contrast puternic cu limbajele mai vechi, cum ar fi C, unele limbaje mai noi, cum ar fi Rust, de exemplu, oferă o funcționalitate încorporată care permite detectarea ușoară și alegerea utilizatorului asupra modului în care ar trebui să fie tratată depășirea de situație de la caz la caz. În Rust, în timp ce utilizarea operatorilor matematici de bază este lipsită în mod natural de o astfel de flexibilitate, utilizatorii pot alternativ să efectueze calcule prin intermediul unui set de metode furnizate de fiecare dintre tipurile primitive de numere întregi. Aceste metode le oferă utilizatorilor mai multe opțiuni între efectuarea unei operații „verificate” (sau de „depășire”) (care indică dacă s-a produs sau nu depășirea prin intermediul tipului de retur); o operație „neverificată”; o operație care efectuează o înfășurare sau o operație care efectuează o saturație la limitele numerice.

Aritmetică saturatăEdit

În grafica pe calculator sau în prelucrarea semnalelor, este tipic să se lucreze cu date care variază de la 0 la 1 sau de la -1 la 1. De exemplu, să luăm o imagine pe scară de gri în care 0 reprezintă negru, 1 reprezintă alb, iar valorile intermediare reprezintă nuanțe de gri. O operațiune pe care se poate dori să o susținem este iluminarea imaginii prin înmulțirea fiecărui pixel cu o constantă. Aritmetica saturată permite să se înmulțească orbește fiecare pixel cu acea constantă, fără a ne face griji cu privire la depășirea limitei, rămânând la un rezultat rezonabil conform căruia toți acești pixeli mai mari decât 1 (adică „mai luminoși decât albul”) devin pur și simplu albi și toate valorile „mai întunecate decât negrul” devin pur și simplu negre..

Lasă un răspuns

Adresa ta de email nu va fi publicată.