Connecting Tech Pros Worldwide Help | Site Map

Converting a hexidecimal string to a floating point array

Bushido Hacks
Guest
 
Posts: n/a
#1: Jul 23 '05
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 };

Victor Bazarov
Guest
 
Posts: n/a
#2: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Bushido Hacks wrote:[color=blue]
> 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 };[/color]

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


Wolfgang Draxinger
Guest
 
Posts: n/a
#3: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Victor Bazarov wrote:
[color=blue]
> using / and %, then do the division by 255. like before.[/color]

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
--

abecedarian@spambob.com
Guest
 
Posts: n/a
#4: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Wolfgang Draxinger wrote:[color=blue]
> Victor Bazarov wrote:
>[color=green]
> > using / and %, then do the division by 255. like before.[/color]
>
> 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?[/color]

Hear, hear! A real expert speaking!

JB West
Guest
 
Posts: n/a
#5: Jul 23 '05

re: Converting a hexidecimal string to a floating point array



"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:edqdnd6mrO9CTu7fRVn-3A@comcast.com...[color=blue]
> Bushido Hacks wrote:[color=green]
> > 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 };[/color]
>
> 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
>
>[/color]

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


Victor Bazarov
Guest
 
Posts: n/a
#6: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Wolfgang Draxinger wrote:[color=blue]
> Victor Bazarov wrote:
>[color=green]
>> using / and %, then do the division by 255. like before.[/color]
>
> 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?[/color]

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


Peter Koch Larsen
Guest
 
Posts: n/a
#7: Jul 23 '05

re: Converting a hexidecimal string to a floating point array



"Wolfgang Draxinger" <wdraxinger@darkstargames.de> skrev i en meddelelse
news:915dk2-7rs.ln1@darkstargames.dnsalias.net...[color=blue]
> Victor Bazarov wrote:
>[color=green]
>> using / and %, then do the division by 255. like before.[/color]
>
> 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?[/color]

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

i/128 -or- 1 >> 7 ?

The naïve 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 naïve programmer like me?

/Peter
[color=blue]
>
> Wolfgang Draxinger
> --
>[/color]


Bushido Hacks
Guest
 
Posts: n/a
#8: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


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.

Alvin
Guest
 
Posts: n/a
#9: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Bushido Hacks wrote:
[color=blue]
> 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.[/color]

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
Peter Koch Larsen
Guest
 
Posts: n/a
#10: Jul 23 '05

re: Converting a hexidecimal string to a floating point array



"Bushido Hacks" <bushidohacks@gmail.com> skrev i en meddelelse
news:1114914182.889555.189010@z14g2000cwz.googlegr oups.com...[color=blue]
> 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.
>[/color]
That question was answered in Victor Bazarovs reply - so why this post?

/Peter


ben
Guest
 
Posts: n/a
#11: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


> The answer has been given. Ignore the #. Read two chars from the string.[color=blue]
> 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.[/color]

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

ben


Jack Klein
Guest
 
Posts: n/a
#12: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


On Sat, 30 Apr 2005 22:05:27 +0200, Wolfgang Draxinger
<wdraxinger@darkstargames.de> wrote in comp.lang.c++:
[color=blue]
> Victor Bazarov wrote:
>[color=green]
> > using / and %, then do the division by 255. like before.[/color]
>
> 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[/color]

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
Martin Steen
Guest
 
Posts: n/a
#13: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Bushido Hacks schrieb:[color=blue]
> 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 };
>[/color]

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;
}
Karl Heinz Buchegger
Guest
 
Posts: n/a
#14: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Martin Steen wrote:[color=blue]
>
>
> 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;[/color]

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
kbuchegg@gascad.at
Martin Steen
Guest
 
Posts: n/a
#15: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Karl Heinz Buchegger wrote:

[color=blue][color=green]
>>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;[/color]
>
>
> 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'.
>[/color]

For real?

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

Best regards, Martin
Larry I Smith
Guest
 
Posts: n/a
#16: Jul 23 '05

re: Converting a hexidecimal string to a floating point array


Bushido Hacks wrote:[color=blue]
> 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 };
>[/color]

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.
Closed Thread