Deplasare logică

operație la nivel de biți în informatică
Operatori de deplasare logică în diverse
limbaje de programare și procesoare
Limbaj sau procesor Stânga Dreapta
Ada[1] Shift_Left Shift_Right
Batch,[2] C, C++, Go, Swift (doar tipuri fără semn);
Standard ML, Verilog, PHP, Python,[3] Rust[4]
<< >>
D, Java, JavaScript, Julia << >>>
F# (doar tipuri fără semn) <<< >>>
Fortran LSHIFT RSHIFT
OCaml lsl lsr
Object Pascal, Delphi, asamblor x86, Kotlin, PowerShell shl shr
Limbaj de descriere Hardware VHSIC (VHDL), MIPS sll srl
PowerPC slw srw

În informatică, o deplasare logică este o operație pe biți⁠(d) care schimbă toți biții operandului său. Cele două variante de bază sunt deplasarea logică la stânga și deplasarea logică 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 sau deplasare la dreapta cu n poziții. Spre deosebire de o deplasare aritmetică, o deplasare logică nu păstrează bitul semn al unui număr sau nu distinge exponentul al unui număr de mantisa sa; fiecare bit din operand este mutat pur și simplu un număr dat de poziții de biți, iar pozițiile de biți libere sunt completate, de obicei cu zerouri și eventual cu unu, în contrast cu o deplasare circulară.

O deplasare logică este adesea folosită atunci când operandul său este tratat ca un șir de biți în loc să fie considerat un număr.

Deplasările logice pot fi utile ca modalități eficiente de a efectua înmulțirea sau împărțirea numerelor întregi fără semn cu puteri ale lui 2. La un număr binar fără semn, deplasarea la stânga cu n poziții a reprezentării sale are ca efect înmulțirea acestuia cu 2n. Deplasarea la dreapta cu n poziții are ca efect împărțirea lui la 2n (rotunjind spre 0).

Deplasarea logică la dreapta diferă de deplasarea aritmetică la dreapta. Astfel, multe limbaje au operatori diferiți pentru ele. De exemplu, în Java și JavaScript, operatorul logic de deplasare la dreapta este >>>, dar operatorul aritmetic de deplasare la dreapta este >>. (Java are un singur operator de deplasare la stânga (<<), deoarece deplasarea la stânga logică și aritmetică au același efect.)

Limbajele de programare C, C++ și Go, au, totuși, un singur operator de deplasare la dreapta, >>. Majoritatea implementărilor C și C++ și Go, aleg ce schimbare la dreapta să efectueze în funcție de tipul de întreg care este deplasat: întregii cu semn sunt deplasați folosind deplasarea aritmetică, iar întregii fără semn sunt deplasați folosind deplasarea logică.

În niciunul dintre standardele C relevante în prezent (ISO/IEC 9899:1999 până în 2011) nu se sunt precizate în definiții cazurile în care numărul de deplasări este egal sau mai mare decât numărul de biți din operanzi, un mod pentru care rezultatul este nedefinit. Acest lucru permite compilatoarelor C să genereze cod eficient pentru diverse platforme, permițând utilizarea directă a instrucțiunilor native de deplasare, care au un comportament diferit. De exemplu, shift-left-word în PowerPC alege comportamentul mai intuitiv în care deplasarea cu numărul de poziții sau mai mult dă zero,[5] întrucât în x86 instrucțiunea SHL alege să mascheze deplasarea biților inferiori „pentru a reduce timpul maxim de execuție al instrucțiunilor” deoarece asta nu shimbă rezultatul.[6]

Unele limbaje, cum ar fi .NET Framework și LLVM, lasă, de asemenea, deplasarea cu numărul de biți ai reprezentării nespecificată (.NET)[7] sau nedefinită (LLVM).[8] Alții aleg să specifice comportamentul celor mai comune platforme țintă, cum ar fi C# care specifică comportamentul x86.[9]

Exemplu modificare

Dacă șirul de biți 0001 0111 (23 în zecimal, reprezentat pe un octet) este deplasat logic cu o poziție, atunci:

Deplasarea la stânga dă: 0010 1110 (46 în zecimal)
 
Deplasare logică la stânga cu o poziție
Deplasarea la dreapta dă: 0000 1011 (11 în zecimal)
 
Deplasare logică la dreapta cu o poziție
Notă: MSB = bitul cel mai semnificativ, LSB = bitul cel mai puțin semnificativ.

Note modificare

  1. ^ en Annotated Ada Reference Manual
  2. ^ en SET la SS64
  3. ^ en „BitwiseOperators - Python Wiki”. wiki.python.org. Accesat în . 
  4. ^ en „Shl in std::ops - Rust”. doc.rust-lang.org. Accesat în . 
  5. ^ en „PowerPC Instruction Set: slw”. pds.twi.tudelft.nl. Arhivat din original la . Accesat în . 
  6. ^ en „x86 Instruction Set Reference”. x86.renejeschke.de. Arhivat din original la . Accesat în . 
  7. ^ en „Opcodes.Shl Field”. msdn.microsoft.com. Microsoft. Accesat în . 
  8. ^ en „LLVM Language Reference Manual - shl Instruction”. llvm.org. LLVM Project. Accesat în . 
  9. ^ en „<< Operator (C# Reference)”. msdn.microsoft.com. Microsoft. Accesat în .