Förklara detta till mig och ge mig ett annat exempel att lösa:
En industrirobot utvärderar och testar varje vecka samma 60 enheter under ca ett år, som ett led i företagets kvalitetsarbete. Varje enhet blir då markerad som Godkänd eller Underkänd vid respektive testtillfälle. Resultatet av en veckas testning med 60 enheter skulle då kunna lagras i en unsigned long int, där resultatet av dessa 60 enheter representeras som ett bitmönster, där varje bit motsvarar en av dessa enheter. Roboten måste alltså kunna "sätta" (enheten godkänd), "släcka" (enheten underkänd), och "testa" värdet på individuella bitar. Skriv funktionerna setBit, clearBit och checkBit, så att följande testprogram fungerar som avsett:
unsigned long week01; // samma som unsigned long int …
setBit(week01, 26); setBit(week01, 20); std::cout << checkBit(week01, 26) << std::endl;
clearBit(week01, 26); std::cout << checkBit(week01, 26) << std::endl
Det verkar som att vi talar om programmering där variabler och bitmanipulation används för att hålla reda på resultatet av kvalitetstester utförda av en industrirobot. För att skapa funktionerna setBit
, clearBit
, och checkBit
, kan vi använda bitvis operationer i C++.
Här är de funktioner som beskrivs i uppgiften:
void setBit(unsigned long &num, int index) { num |= 1UL << index; } void clearBit(unsigned long &num, int index) { num &= ~(1UL << index); } bool checkBit(const unsigned long &num, int index) { return (num >> index) & 1UL; }
Förklaring av varje funktion:
setBit
: Sätter biten på specifik plats (index) till 1. Detta görs genom att först skifta 1 till vänster index
antal gånger, vilket skapar ett tal där endast biten på platsen "index" är 1 och resten är 0. Därefter använder vi en OR operation |
för att uppdatera num
.
clearBit
: Nollställer biten på specifik plats (index). Detta görs genom att först skapa ett tal där alla bitar är 1 förutom på plats "index" genom uttrycket ~(1UL << index)
, och sedan använda en AND operation &
för att uppdatera num
.
checkBit
: Kontrollerar bitvärdet på en specifik plats (index) genom att skifta num
index
antal gånger till höger och sedan kontrollera om den minst signifikanta biten är 1 eller 0.
När du använder dessa funktioner som beskrivet i uppgiften, ser testprogrammet ut så här:
#include <iostream> // Funktionerna setBit, clearBit, och checkBit som definieras här... int main() { unsigned long week01 = 0; // Initierar week01 till 0 för att börja med ett rent bitmönster setBit(week01, 26); setBit(week01, 20); std::cout << checkBit(week01, 26) << std::endl; // Skriver ut 1 eftersom biten är satt clearBit(week01, 26); std::cout << checkBit(week01, 26) << std::endl; // Skriver ut 0 eftersom biten är rensad (klar) return 0; }
För att ge ett annat exempel för dig att lösa, låt oss säga att vi vill testa en annan vecka med olika enheter och se resultatet av dessa tester:
int main() { unsigned long week02 = 0; setBit(week02, 4); setBit(week02, 15); setBit(week02, 30); // Sätter bitar 4, 15 och 30 till '1' (Godkänd) std::cout << checkBit(week02, 15) << std::endl; // Förväntar sig att skriva ut 1 eftersom enhet 15 är godkänd clearBit(week02, 15); // Enhet 15 testades igen och underkändes std::cout << checkBit(week02, 15) << std::endl; // Förväntar sig att skriva ut 0 eftersom enhet 15 nu är underkänd // Lägg till tester för att verifiera status på andra enheter... return 0; }
Här har du ett nytt scenario att implementera. Använd samma funktioner som tidigare men med en ny uppsättning av operationer och kontroller.
lösningen var detta:
void setBit( unsigned long &a, int bit){¬ 6 a |= 1UL << bit;¬ 7 }¬ 8 ¬ 9 void clearBit( unsigned long &a, int bit){¬ 10 a &= ~(1UL << bit);¬ 11 }¬ 12 ¬ 13 bool checkBit( unsigned long &a, int bit){¬ 14 //return (a >> bit) & 1; // alternativ.¬ 15 return (a & (1UL << bit));¬ 16 }
Hur kommer jag till det steg för ste.
För att lösa detta problem behöver vi förstå några grundläggande koncept inom bitmanip och hur man använder bitvis AND, OR och NOT-operationer i C++ för att modifiera och kontrollera individuella bitar in en datatyp som unsigned long
.
Så här kommer fram till varje funktion, steg för steg:
setBit
För att "sätta (göra till 1) en specifik bit behöver vi:
Skapa ett bitmönster där endast den bit ska sättas är 1 och resten är 0. Detta uppnår du med uttrycket 1 << bit
.
|
) för att sätta den specifika biten utan att påverka andra bitar.St steg:
A. 1UL
är ett litteral uttryck för en lå konstant (unsigned long
) med värdet 1.
B. <<
utför en vänsterskiftoperation, vil flyttar 1 till bitpositionen vi vill sätta.
C. |= ...
använder bitvis OR för att uppda a
och sätta den specifierade biten.
clearBit
ör att "släcka" (göra till 0 en specifik bit behöver vi:
~(1UL << bit)
.&
) för att nollställa den specifikaen utan att påverka andra bitar.Steg steg:
A. Skifta 1 till rätt position som i setBit
för att skapa ett bitmönster med aktuella biten som 1.
B. Bitvis NOT (``) inverterar detta bitmönster så att alla bitar blir 1 förutom den biten vi vill rensa, som blir 0.
. a &= ...
använder bitvis AND för att uppdatera a
och rens den specifierade biten.
check
För att "testa" (kontrollera värde på) en specifik bit behö vi:
Steg för steg:
A. Skapa bitmönster som i setBit
där bara den biten vi vill testa är 1.
B. a & ...
använder bitvis AND för att isolera biten på ökad position.
C. Om resultatet inte är 0, så är biten satt (returnerar "true om man använder en boolsk returvärde).
Här är hela exem implementerat enligt dessa steg:
void setBit(unsigned longa, int bit) { a |= 1UL bit; } void clearBit(unsigned long &a, int bit) { a &= ~(1UL << bit); } checkBit(unsigned long &a, int bit) { (a & (1UL << bit)) != 0; }
Funktionen checkBit
den lösning du gav kan returnera vilketärde som helst som inte är noll om biten satt. Om du att den strikt ska returnera en bool
, true
eller false
,mför du resultatet med 0, som jag har gjort i min versionAnvändningen av dessa funktioner i ett faktiskt testprogram skulle tillåta dig att hålla reda tillståndet för de 60 enheterna roboten testar varjecka.
kan du ritta upp stegen textuellt så jag förstår
Absolut, låt oss bryta ner varje steg textuellt för att förstå hur man genomför varje bitoperation:
setBit
)Målet: Vi vill sätta en specifik bit till 1.
Steg-för-steg:
Steg 1: Bestäm bitens position. Om vi vill sätta biten på position bit
, så räknar vi bitpositionen från höger med start vid 0.
Steg 2: Skapa ett bitmönster där endast den bit som ska sättas är 1. Det gör man genom att skifta 1
vänster bit
gånger, vilket ger oss 1UL << bit
.
Steg 3: Använd bitvis OR (|
) för att sätta den önskade biten. Det gör att alla bitar som är 1 i antingen det ursprungliga numret a
eller i "masken" vi har skapat (från steg 2) kommer att vara 1 i det resulterande numret.
clearBit
)Målet: Vi vill sätta en specifik bit till 0.
Steg-för-steg:
Steg 1: Bestäm bitens position, liknande som för setBit
.
Steg 2: Skapa ett bitmönster där alla bitar är 1, förutom på den position där du vill nollställa biten, det vill säga biten på position bit
ska vara 0. Detta görs genom att först skifta 1
vänster bit
gånger som tidigare, och sedan ta negationen av den bitmönstret: ~(1UL << bit)
.
Steg 3: Använd bitvis AND (&
) med det inverterade bitmönstret. Det garanterar att biten på position bit
blir nollställd i variabeln a
, medan alla andra bitar förblir oförändrade.
checkBit
)Målet: Vi vill kontrollera om en specifik bit är satt (det vill säga är 1).
Steg-för-steg:
Steg 1: Bestäm bitens position, återigen på samma sätt.
Steg 2: Skapa ett bitmönster precis som i setBit
, där endast den biten som ska kontrolleras är 1: 1UL << bit
.
Steg 3: Använd nu bitvis AND (&
) mellan variabeln a
och bitmönstret du skapat. Om biten på position bit
är satt i a
, kommer resultatet att bli en icke-noll siffra (precis det bitmönstret vi skapat). Om biten inte är satt, kommer resultatet bli 0.
Steg 4: Returnera om resultatet från steg 3 inte är 0 för att indikera true
(biten är satt), eller returnera false
om resultatet är 0 (biten är inte satt).
Att transformera dessa steg till kod ger oss de funktioner som presenterades tidigare. Varje steg bygger på att vi använder bitoperationer för att manipulera individuella bitar inuti en unsigned long
variabel.