Deplasare aritmetică

operație la nivel de biți în informatică

În informatică, o deplasare aritmetică este o operație pe biți⁠(d) care schimbă toți biții operandului său. Cele două variante de bază sunt deplasarea aritmetică la stânga și deplasarea aritmetică la dreapta. Aceasta este comandată de numărul de poziții de biți pe care o anumită valoare va fi deplasată, cum ar fi deplasare la stânga cu 1 poziție sau deplasare la dreapta cu n poziții. Fiecare bit din operand este mutat un număr dat de poziții de biți, iar pozițiile de biți libere sunt completate cu zerouri la drepta, respectiv cu valoarea din primul bit (bitul semn⁠(d)) la stânga.

O deplasare aritmetică la dreapta a unui număr binar cu 1 poziție. Poziția goală din bitul cel mai semnificativ este completată cu o copie a bitului original.
Notă:
MSB = bitul cel mai semnificativ,
LSB = bitul cel mai puțin semnificativ.
O deplasare aritmetică la stânga a unui număr binar cu 1 poziție. Poziția goală din bitul cel mai puțin semnificativ este completată cu 0.
Operatori de deplasare aritmetică în diverse limbaje de programare și procesoare
Limbaj sau procesorStângaDreapta
ActionScript 3, Java, JavaScript, Python, PHP, Ruby;
C, C++,[1]D, C#, Go, Julia, Swift (doar tipuri fără semn)[a]
<< >>
Ada Shift_Left [2] Shift_Right_Arithmetic
Kotlin shl shr
Standard ML << ~>>
Verilog <<< >>> [b]
Limbajul macro OpenVMS@[c][3]
Schemearithmetic-shift[d]
Common Lispash
OCamllslasr
HaskellData.Bits.shift[e]
Asamblor, 68kASLASR
Asamblor, x86SALSAR
VHDLsla[f]sra
RISC-Vsll, slli[4]sra, srai
Z80SLA[5]SRA

Deplasările aritmetice pot fi utile ca modalități eficiente de a efectua înmulțirea sau împărțirea numerelor întregi cu semn cu puteri ale lui 2. Deplasarea la stânga cu n biți a unui număr binar cu semn sau fără semn are ca efect înmulțirea acestuia cu 2n. Deplasarea la dreapta cu n biți a unui complement față de doi cu semn are efectul de a-l împărți la 2n, dar se rotunjește întotdeauna în jos (spre infinitul negativ). Acest lucru este diferit de modul în care rotunjirea se face de obicei la împărțirea întregilor cu semn (care se rotunjește spre 0). Această discrepanță a dus la erori într-un număr de compilatoare.[6] De exemplu, în setul de instrucțiuni al x86, instrucțiunea SAR (deplasare aritmetică la dreapta) împarte un număr cu semn la o putere a lui 2, rotunjind spre infinitul negativ,[7] însă, instrucțiunea IDIV (împărțire cu semn) împarte un număr cu semn rotunjind spre zero. Deci o instrucțiune SAR nu poate fi înlocuită de un IDIV și nici invers.

Definiție formală

Definiția formală a unei deplasări aritmetice, din Standardul federal 1037C este:

O deplasare, aplicată reprezentării unui număr într-un sistem de numerație cu o bază de numerație fixă și într-un sistem de reprezentare în virgulă fixă, mută doar caracterele din partea reprezentată în virgulă fixă a numărului. O deplasare aritmetică este de obicei echivalentă cu înmulțirea numărului cu o putere întreagă pozitivă sau negativă a bazei de numerație, cu excepția efectului vreunei rotunjiri; a se compara deplasarea logică cu deplasarea aritmetică, mai ales în cazul reprezentării în virgulă mobilă.

O expresie importantă în definiția FS 1073C este „de obicei”.

Echivalența deplasărilor aritmetice și logice la stânga cu înmulțirea

Deplasările aritmetice la stânga sunt echivalente cu înmulțirea cu o putere (pozitivă, întreagă) a bazei de numerație (de exemplu, o înmulțire cu o putere a lui 2 pentru numerele binare). Deplasările logice la stânga sunt, de asemenea, echivalente, cu excepția faptului că înmulțirile și deplasările aritmetice pot declanșa depășirea aritmetică⁠(d) (întreagă), în timp ce deplasările logice nu.

Neechivalența deplasărilor aritmetice la dreapta cu împărțirea

Deplasările aritmetice dreapta sunt capcane majore pentru cei imprudenți, în special în tratarea rotunjirii numerelor întregi negative. De exemplu, în reprezentarea obișnuită în complement față de doi a numerelor întregi negative, −1 este reprezentat cu toate cifrele binare „1”. Pentru un număr întreg cu semn pe 8 biți, acesta este 1111 1111. O deplasare aritmetică la dreapta cu 1 (sau 2, 3, ..., 7) dă tot 1111 1111, care este tot −1. Aceasta corespunde rotunjirii în jos (spre infinit negativ), dar nu este convenția obișnuită la împărțire.

Se afirmă frecvent că deplasările aritmetice la dreapta sunt echivalente cu împărțirea la o putere (pozitivă, integrală) a bazei de numerație (de exemplu, o împărțire cu o putere a lui 2 pentru numere binare) și, prin urmare, că diviziunea cu o putere a bazei poate fi optimizată prin implementarea acesteia ca o deplasare aritmetică la dreapta. (O deplasare este mult mai simplă decât o împărțire. La majoritatea procesoarelor, instrucțiunile de deplasare se vor executa mai rapid decât instrucțiunile de împărțire.) Un mare număr de manuale de programare și alte specificații din anii 1960 și 1970 de la companii și instituții precum DEC, IBM, Data General și ANSI fac astfel de declarații incorecte.[8].

Deplasările logice la dreapta sunt echivalente cu împărțirea cu o putere a bazei (de obicei 2) numai pentru numerele pozitive sau fără semn. Deplasările aritmetice la dreapta sunt echivalente cu deplasările logice la dreapta pentru numerele cu semn pozitiv. Deplasările aritmetice la dreapta pentru numerele negative în complementul lui N−1 (de obicei complementul față de doi) sunt aproximativ echivalente cu împărțirea cu o putere a bazei (de obicei 2), unde pentru numerele impare se aplică rotunjirea în jos (nu spre 0, ca de obicei).

Deplasările aritmetice la dreapta pentru numerele negative sunt echivalente cu împărțirea folosind rotunjirea spre 0 în reprezentarea numerelor cu semn în complement față de unu⁠(d), așa cum a fost folosit de unele calculatoare istorice, dar acest lucru nu mai este de uz general.

Gestionarea problemei în limbajele de programare

Standardul ISO (1999) pentru limbajul de programare C definește operatorul de deplasare la dreapta în termenii împărțirii la puteri ale lui 2.[9] Din cauza neechivalenței menționate mai sus, standardul exclude în mod explicit din această definiție deplasările la dreapta ale numerelor cu semn care au valori negative. Nu specifică comportamentul operatorului de deplasare la dreapta în astfel de circumstanțe, ci solicită ca pentru fiecare compilator C să de definească individual comportamentul deplasării la dreapta a valorilor negative.[11]

Aplicații

În aplicațiile în care se dorește o rotunjire consecventă în jos, sunt utile deplasările aritmetice la dreapta pentru valorile cu semn. Un exemplu este în scalarea în jos a coordonatelor de tip raster cu o putere a lui doi, care menține spațierea uniformă. De exemplu, deplasarea la dreapta cu 1 trimite 0, 1, 2, 3, 4, 5, ... la 0, 0, 1, 1, 2, 2, ... și −1, −2, −3, −4, ... la −1, −1, −2, −2, ..., menținând spațierea pară ca −2, −2, −1, −1, 0, 0, 1, 1, 2, 2 , ... Prin contrast, împărțirea întregilor cu rotunjire spre zero trimite pe toate −1, 0 și 1 la 0 (3 puncte în loc de 2), rezultând −2, −1, −1, 0, 0, 0, 1, 1, 2, 2, ... , care este neregulat în 0.

Note explicative

Note

Bibliografie

🔥 Top keywords: Pagina principalăSpecial:CăutareCS Corvinul HunedoaraFlorin MaximNoua CaledonieSlovaciaRomâniaIl VoloGen non-binarȘtefan cel MareSfinții Împărați Constantin și ElenaCupa României la fotbalXXX: Return of Xander CageRobert FicoUniunea EuropeanăAl Doilea Război MondialFlorin PiersicYouTubeZodiacVlad ȚepeșMihai EminescuAlegeri prezidențiale în România, 2024BucureștiSocietatea Română de TeleviziuneCarol I al RomânieiMihai ViteazulSpecial:Schimbări recenteRepublica Moldova16 maiNicolae CeaușescuHunedoaraUltima noapte de dragoste, întâia noapte de războiPrimul Război MondialFranțaAlexandru Ioan CuzaLista orașelor din RomâniaLista prefixelor telefonice internaționaleO scrisoare pierdutăLista capitalelor europene după suprafață