# Float To 3 unsigned chars

Printable View

• 07-03-2009
appleGuy
Float To 3 unsigned chars
Hi,

I want to be able to convert a float to 3 unsigned chars (as in part of the float in each unsigned char) and also be able to compare the float to the equivalent value of the 3 unsigned chars.

float will be between 0 and -1.0

I hope that makes sense :S

Many Thanks,
• 07-03-2009
scwizzo
Each part of the decimal in to an unsigned char? Try reading the float in to a string, and then pull out the part you want in to a single char.
• 07-03-2009
appleGuy
Quote:

Originally Posted by scwizzo
Each part of the decimal in to an unsigned char? Try reading the float in to a string, and then pull out the part you want in to a single char.

Its not the literal displayed values... ill try to give an example

-1.0 = 255, 255, 255

-0.x = ???, ???, ???

0.0 = 0, 0, 0
• 07-03-2009
legit
Is there a relation between the float value and the values that you want to extract?
• 07-03-2009
appleGuy
Quote:

Originally Posted by legit
Is there a relation between the float value and the values that you want to extract?

OK, I will explain what i am trying to do...

I am trying to implement a z buffer algorithm for a software renderer. Pixels come in with a particular depth between 0.0 and -1.0. I want to be able to store these depths (for later comparisons) in a depth buffer that is really an image consisting of 3 unsigned chars per pixel (RGB). A Pixel In The rendered image has the same pixel location as its depth in the depth buffer, therefore I have 3 * unsigned chars to play with
• 07-03-2009
Cactus_Hugger
I'm not entirely sure what you're trying to do here, but if your floats are in the range of [-1, 0], then you could scale that to [0, 2^24-1], and then store than in an integer. Then store 8 of the 24 bits in one of your colors.

If you had a 32bit image, you could probably stuff the entire float in, since an IEEE float is 32bit.

But this whole thing feels like you're pushing a square peg into a round hole.
• 07-03-2009
Dave Evans
Quote:

Originally Posted by appleGuy
Its not the literal displayed values... ill try to give an example

-1.0 = 255, 255, 255

-0.x = ???, ???, ???

0.0 = 0, 0, 0

You want to interpolate each rgb value.

The formula for linear interpolation is f(x) = f(a) + (b-a)/(x-a) * (f(b)-f(a))

If a = 0.0, b = -1.0, f(a) = 0, f(b) = 255 it could go something like

Code:

```    const double a = 0.0;     const double b = -1.0;     const double fa = 0.0;     const double fb = 255.0;     double x;     unsigned char pixelval; . . .     /* get a value of x from somewhere.  Presumably can be anything from a to b */     pixelval = (fa + (x-a)/(b-a)*(fb-fa))+0.5; /* round the positive float to the "nearest" integer */```
If all of the min pixel values are zero and all of the max pixel values are 255, then you call this function once and assign the same calculated pixel value to r, g, and b.

D.
• 07-03-2009
scwizzo
Why wouldn't something as easy as this work?
Code:

`unsigned char pixel = depth*(-255.0);`
Since you know the values are between 0 and -1 then the pixel value will be anything between 0 and 255, and can be later referenced to decide what the depth originally was.
• 07-04-2009
iMalc
Quote:

Originally Posted by Cactus_Hugger
I'm not entirely sure what you're trying to do here, but if your floats are in the range of [-1, 0], then you could scale that to [0, 2^24-1], and then store than in an integer. Then store 8 of the 24 bits in one of your colors.

If you had a 32bit image, you could probably stuff the entire float in, since an IEEE float is 32bit.

But this whole thing feels like you're pushing a square peg into a round hole.

What Cactus has described here is the way to go. Multiply by -16777215 and cast to int and then you have a number from 0x000000 to 0xFFFFFF. Done.
The bad thing though is that in order to compare depths later, you have to reconstruct the int value, which is additional overhead. If you multiplied by -65535 instead and only used two of the bytes to store it, then you have less work to reconstruct the value later and the result should be approximately as good. You could cast the address of those 3 bytes as a pointer to short, mask off the lowest bit of the pointer, and then access it directly as a nicely-aligned short, for better performance.
For that matter, why don't you just treat it as an array of unsigned shorts directly, completely ignoring the upper one third of the bytes?

I have my own hobby software renderer, so I have a pretty good idea of what is faster most of the time.