2

I have to solve a problem that requires to convert RGB to Hex. I found a solution online, but I don't understand the purpose of the constants 16 and 8. Can someone, please, explain this to me? Thank you

#include <iostream>
#include <sstream>
using namespace std;


int main(){
    stringstream ss;
    int r,g,b;
    cout << "testing" << endl;
    cin >> r >> g >> b;
    
    ss << "#" << hex << (r << 16 | g << 8 | b);
    cout << ss.str();

  

    return 0;
    
}
zkoza
  • 2,644
  • 3
  • 16
  • 24
  • 4
    I think this might be an incorrect solution, since if `r=0, g=11, b=22`, `ss` would be `#1122` but you would expect `#001122`. – Superior Aug 14 '21 at 22:36
  • 2
    @Superior You are right about the leading zeros, but note that `11 != 0x11`, so the expected output is your case should differ. – chi Aug 15 '21 at 08:02
  • You are going to run into problems building your string unless you look at [Input/output manipulators](https://en.cppreference.com/w/cpp/io/manip) (e.g. `#include `) and particularly [std::setw()](https://en.cppreference.com/w/cpp/io/manip/setw) and [std::setfill()](https://en.cppreference.com/w/cpp/io/manip/setfill). Then have a look at [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/q/1452721/364696) – David C. Rankin Aug 16 '21 at 07:37

3 Answers3

5

The expression r << 16 shifts the value of r left by 16 bits, making it bits 16 to 23 of your number.

The expression g << 8 shifts the value of g left by 8 bits, making it bits 8 to 15 of your number.

Then the expression b is not shifting anything, making it the bits 0 to 7 in your number.

The bitwise or | is then used to combine all these numbers into a single 32-bit int value, where bits 24 to 31 are zero (assuming you only entered values in the range of 0 to 255 as input).

This should all really be part of any decent text-book, class or tutorial.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

I think this might be an incorrect solution, since if r=0x00, g=0x11, b=0x22, ss would be #1122 but you would expect #001122.

aside from checks if values are in range [0, 255]
I'd do it like this

char h[8]; // # + 6 digits + \0
int r,g,b;
cout << "testing" << endl;
cin >> r >> g >> b;

// %x formats int to hex string, 
// 02 means fill with zeros to length 2
// this is applied to each r, g, b
sprintf(h, "#%02x%02x%02x", r, g, b); 
cout << h;
Superior
  • 787
  • 3
  • 17
0

to generate rgb you need 3bytes, one byte have 8 bits then the result is like this:

00000000 00000000 00000000

to generate r will be 16 to 23

to generate g will be 8 to 15

to generate b will be 0 to 7

in code your code is doing this

int color = red*256*256 + green*256 + blue;

 b = color % 256;
 g = (color % (256*256) - b) /256;
 r = (color - b - g*256) / (256*256);