By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,771 Members | 1,685 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,771 IT Pros & Developers. It's quick & easy.

Converting a hexidecimal string to a floating point array

P: n/a
Hey c.l.c++ and/or c.g.a.opengl posters,

How do I convert a hexidecimal string, traditionally used for defining
colors with HTML, into a floating point array?

In other words, how do I convert this:
char* hex = "#FF9933";

into this:

float fpa = { 1.0, 0.6, 0.2 };

Jul 23 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a
Bushido Hacks wrote:
Hey c.l.c++ and/or c.g.a.opengl posters,

How do I convert a hexidecimal string, traditionally used for defining
colors with HTML, into a floating point array?

In other words, how do I convert this:
char* hex = "#FF9933";

into this:

float fpa = { 1.0, 0.6, 0.2 };


Skip the #, extract the first two hex digits and convert it to
an integer from base-16 string using strtol, divide the integer
by 255. (double constant, don't forget the dot). Then repeat
for the other two pairs of hex digits. Wrap it up in a function
and you get yourself something you can use over and over. Or
you could do it without extracting digits. Just convert the
entire number into a long, then split it into three integers
using / and %, then do the division by 255. like before.

V
Jul 23 '05 #2

P: n/a
Victor Bazarov wrote:
using / and %, then do the division by 255. like before.


division and module are expensive. Better is bitwise masking and
bitshifting. It's strange but I've seen a lot of programs using
division and module for operaions that would have been better
done with bitwise operations. Is there a certain reason other
than ignorance?

Wolfgang Draxinger
--

Jul 23 '05 #3

P: n/a
Wolfgang Draxinger wrote:
Victor Bazarov wrote:
using / and %, then do the division by 255. like before.


division and module are expensive. Better is bitwise masking and
bitshifting. It's strange but I've seen a lot of programs using
division and module for operaions that would have been better
done with bitwise operations. Is there a certain reason other
than ignorance?


Hear, hear! A real expert speaking!

Jul 23 '05 #4

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ed********************@comcast.com...
Bushido Hacks wrote:
Hey c.l.c++ and/or c.g.a.opengl posters,

How do I convert a hexidecimal string, traditionally used for defining
colors with HTML, into a floating point array?

In other words, how do I convert this:
char* hex = "#FF9933";

into this:

float fpa = { 1.0, 0.6, 0.2 };


Skip the #, extract the first two hex digits and convert it to
an integer from base-16 string using strtol, divide the integer
by 255. (double constant, don't forget the dot). Then repeat
for the other two pairs of hex digits. Wrap it up in a function
and you get yourself something you can use over and over. Or
you could do it without extracting digits. Just convert the
entire number into a long, then split it into three integers
using / and %, then do the division by 255. like before.

V


If you are using as a color argument, you may not need to convert to float.
Just parse & pass to OpenGL. void glColor3us( GLushort red, GLushort green,
GLushort blue )
-jbw
Jul 23 '05 #5

P: n/a
Wolfgang Draxinger wrote:
Victor Bazarov wrote:
using / and %, then do the division by 255. like before.


division and module are expensive. Better is bitwise masking and
bitshifting. It's strange but I've seen a lot of programs using
division and module for operaions that would have been better
done with bitwise operations. Is there a certain reason other
than ignorance?


For 255 (256) there probably isn't. For other values there may
not be a simple solution using bit shifts and masks.
Jul 23 '05 #6

P: n/a

"Wolfgang Draxinger" <wd********@darkstargames.de> skrev i en meddelelse
news:91************@darkstargames.dnsalias.net...
Victor Bazarov wrote:
using / and %, then do the division by 255. like before.
division and module are expensive. Better is bitwise masking and
bitshifting. It's strange but I've seen a lot of programs using
division and module for operaions that would have been better
done with bitwise operations. Is there a certain reason other
than ignorance?


Well, if you divide i by 128 what expression looks best?

i/128 -or- 1 >> 7 ?

The nave programmer might prefer the first one, but any expert hacker would
naturally prefer option number 2.

The only problem is that the second option is non-portable whereas the first
is fine - and just as fast on any compiler i've encountered the last 15
years.
So take your poison. Are you a hacker or just a nave programmer like me?

/Peter

Wolfgang Draxinger
--

Jul 23 '05 #7

P: n/a
Gee people. Come'on! IT'S A SIMPLE QUESTION. Im not interested in
doing all this goofy crap right now. I just want to use a simple
straightforward method. I'm not trying to hack the Pentagon.

I want an answer that only uses char, int, double, or float. Not long.
Not short. Not string. And certainly nothing to do with C or Assembly,
or Visual whatever. Just regular ISO standard C++. That's all.

Man. You know what our problem is, we just take thing too literally.
Where as you guys take a ten page list of codes, I could probably
factor into about a page and a half.

And since when did division and mod become expensive operations? I
doubt any of that is true. If they are, why bother using +, -, *, !,
&&, ||, &, |, <, >, == , or even = ?

My only interest in this is to just make a simple OpenGL model using
C++.

I just want to break the string apart into characters. First character
divsible by FF (255) and the second character divsable by F (15) then
add the two digits and assign them to an array of size 3.

But my first road block is to break apart the string. Remember, I want
to use a STRING not an actual hexidecimal.

Jul 23 '05 #8

P: n/a
Bushido Hacks wrote:
Gee people. Come'on! IT'S A SIMPLE QUESTION. Im not interested in
doing all this goofy crap right now. I just want to use a simple
straightforward method. I'm not trying to hack the Pentagon.

I want an answer that only uses char, int, double, or float. Not long.
Not short. Not string. And certainly nothing to do with C or Assembly,
or Visual whatever. Just regular ISO standard C++. That's all.

Man. You know what our problem is, we just take thing too literally.
Where as you guys take a ten page list of codes, I could probably
factor into about a page and a half.

And since when did division and mod become expensive operations? I
doubt any of that is true. If they are, why bother using +, -, *, !,
&&, ||, &, |, <, >, == , or even = ?

My only interest in this is to just make a simple OpenGL model using
C++.

I just want to break the string apart into characters. First character
divsible by FF (255) and the second character divsable by F (15) then
add the two digits and assign them to an array of size 3.

But my first road block is to break apart the string. Remember, I want
to use a STRING not an actual hexidecimal.


The answer has been given. Ignore the #. Read two chars from the string.
Convert those chars into a single number (in base-16...this is important).
Then divide that number by 255. Then convert the resulting number (it will
be a decimal number between 0 and 1) into it's string equivalent.

Alvin
Jul 23 '05 #9

P: n/a

"Bushido Hacks" <bu**********@gmail.com> skrev i en meddelelse
news:11**********************@z14g2000cwz.googlegr oups.com...
Gee people. Come'on! IT'S A SIMPLE QUESTION. Im not interested in
doing all this goofy crap right now. I just want to use a simple
straightforward method. I'm not trying to hack the Pentagon.

I want an answer that only uses char, int, double, or float. Not long.
Not short. Not string. And certainly nothing to do with C or Assembly,
or Visual whatever. Just regular ISO standard C++. That's all.

Man. You know what our problem is, we just take thing too literally.
Where as you guys take a ten page list of codes, I could probably
factor into about a page and a half.

And since when did division and mod become expensive operations? I
doubt any of that is true. If they are, why bother using +, -, *, !,
&&, ||, &, |, <, >, == , or even = ?

My only interest in this is to just make a simple OpenGL model using
C++.

I just want to break the string apart into characters. First character
divsible by FF (255) and the second character divsable by F (15) then
add the two digits and assign them to an array of size 3.

But my first road block is to break apart the string. Remember, I want
to use a STRING not an actual hexidecimal.

That question was answered in Victor Bazarovs reply - so why this post?

/Peter
Jul 23 '05 #10

P: n/a
ben
> The answer has been given. Ignore the #. Read two chars from the string.
Convert those chars into a single number (in base-16...this is important).
Then divide that number by 255. Then convert the resulting number (it will
be a decimal number between 0 and 1) into it's string equivalent.


or simpler: replace "#" with "0x", put it into a stringstream, and read an
int out of it.

ben
Jul 23 '05 #11

P: n/a
On Sat, 30 Apr 2005 22:05:27 +0200, Wolfgang Draxinger
<wd********@darkstargames.de> wrote in comp.lang.c++:
Victor Bazarov wrote:
using / and %, then do the division by 255. like before.


division and module are expensive. Better is bitwise masking and
bitshifting. It's strange but I've seen a lot of programs using
division and module for operaions that would have been better
done with bitwise operations. Is there a certain reason other
than ignorance?

Wolfgang Draxinger


I would be quite surprised to find a compiler on the market today that
did not do the automatic strength reduction for division or modulus of
an integer type by a constant power of 2. Old 16-bit MS-DOS compilers
from Microsoft and Borland were doing this 15 years ago, for example.

The last one I had to use that would actually generate a division for
this became extinct at least five years ago.

But I admit that I will always verify that a new (to me) compiler does
so, and do the shifts and masks in the source in time critical code if
necessary.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 23 '05 #12

P: n/a
Bushido Hacks schrieb:
Hey c.l.c++ and/or c.g.a.opengl posters,

How do I convert a hexidecimal string, traditionally used for defining
colors with HTML, into a floating point array?

In other words, how do I convert this:
char* hex = "#FF9933";

into this:

float fpa = { 1.0, 0.6, 0.2 };


Call the function HexColorToFloat like this:

float FloatColor[3];
HexColorToFloat("FF9933", FloatColor);
/************************************************** ********************/

#include <iostream.h>

static int Getdec(char hexchar)
{
if ((hexchar >= '0') && (hexchar <= '9')) return hexchar - '0';
if ((hexchar >= 'A') && (hexchar <= 'F')) return hexchar - 'A' + 10;
if ((hexchar >= 'a') && (hexchar <= 'f')) return hexchar - 'a' + 10;

return -1; // Wrong character
}

static void HexColorToFloat(char* HexColor, float* FloatColor)
{
char* HexColorPtr = HexColor;

for (int i = 0; i < 3; i++)
{
int IntColor = (Getdec(HexColorPtr[0]) * 16) +
Getdec(HexColorPtr[1]);

FloatColor[i] = (float) IntColor / 255.0;
HexColorPtr += 2;
}
}
int main(int argc, char* argv[])
{
float FloatColor[3];

HexColorToFloat("FF9933", FloatColor);

cout << "r=" << FloatColor[0] << endl;
cout << "g=" << FloatColor[1] << endl;
cout << "b=" << FloatColor[2] << endl;

return 0;
}
Jul 23 '05 #13

P: n/a
Martin Steen wrote:


static int Getdec(char hexchar)
{
if ((hexchar >= '0') && (hexchar <= '9')) return hexchar - '0';
if ((hexchar >= 'A') && (hexchar <= 'F')) return hexchar - 'A' + 10;
if ((hexchar >= 'a') && (hexchar <= 'f')) return hexchar - 'a' + 10;


Neither in C nor in C++ you have the guarantee that the characters
'A' through 'F' have consecutive code values.

But note: You have that guarantee for the characters '0' to '9'.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #14

P: n/a
Karl Heinz Buchegger wrote:

static int Getdec(char hexchar)
{
if ((hexchar >= '0') && (hexchar <= '9')) return hexchar - '0';
if ((hexchar >= 'A') && (hexchar <= 'F')) return hexchar - 'A' + 10;
if ((hexchar >= 'a') && (hexchar <= 'f')) return hexchar - 'a' + 10;

Neither in C nor in C++ you have the guarantee that the characters
'A' through 'F' have consecutive code values.

But note: You have that guarantee for the characters '0' to '9'.


For real?

As long as you use ASCII or Unicode, i suppose this code works. ;)

Best regards, Martin
Jul 23 '05 #15

P: n/a
Bushido Hacks wrote:
Hey c.l.c++ and/or c.g.a.opengl posters,

How do I convert a hexidecimal string, traditionally used for defining
colors with HTML, into a floating point array?

In other words, how do I convert this:
char* hex = "#FF9933";

into this:

float fpa = { 1.0, 0.6, 0.2 };


Here's a couple of example methods:

// hex2rgb.cpp - test some hex to RGB color conversion
// methods.
// compile: g++ -o hex2rgb hex2rgb.cpp
// execute: ./hex2rgb some_hex_string

#include <cstdlib> // for strtoul()
#include <iostream>

// convert a hex color string to three integer RGB values.
// returns zero on success, non-zero on error.
int
hex2rgb(const char * hex, int& red, int& green, int& blue)
{
unsigned long val;

if (NULL == hex)
{
red = green = blue = 0;
return 1;
}

// convert the hex string to an unsigned long int.
// val will be zero if 'hex' is invalid.
// Note: we should check 'errno' after this call
// to see if a conversion error occurred;
// see the docs for strtoul().
val = strtoul(hex, NULL, 16);
red = ((val & 0xff0000) >> 16);
green = ((val & 0xff00) >> 8);
blue = (val & 0xff);

return 0;
}

// convert a hex color string to three float RGB values.
// returns zero on success, non-zero on error.
// Note this is the same as the int version except we
// divide each derived RGB color by 255.0. this method
// could simply call the int version then divide those
// results by 255.0 before returning
int
hex2rgb(const char * hex, float& red, float& green, float& blue)
{
unsigned long val;

if (NULL == hex)
{
red = green = blue = 0.0;
return 1;
}

// convert the hex string to an unsigned long int.
// val will be zero if 'hex' is invalid.
// Note: we should check 'errno' after this call
// to see if a conversion error occurred;
// see the man page for strtoul(),
val = strtoul(hex, NULL, 16);

red = ((float)((val & 0xff0000) >> 16)) / 255.0;
green = ((float)((val & 0xff00) >> 8)) / 255.0;
blue = ((float)(val & 0xff)) / 255.0;

return 0;
}
int
main(int argc, char * argv[])
{
if (argc < 2)
{
std::cerr << "Usage: " << argv[0] << " hex_value" << std::endl;
return 1;
}

int ir, ig, ib;
float fr, fg, fb;

// get the int RGB values into ir, ig, and ib
hex2rgb(argv[1], ir, ig, ib);

std::cout << argv[1] << ": red = " << ir << " green = " << ig
<< " blue = " << ib << std::endl;

// get the float RGB values into fr, fg, and fb
hex2rgb(argv[1], fr, fg, fb);

std::cout << argv[1] << ": red = " << fr << " green = " << fg
<< " blue = " << fb << std::endl;

return 0;
}
Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.