Jim - 1 year ago 57

C# Question

I've read several links discussing storing 2 or 3 floats in one float. Here's an example:

Storing two float values in a single float variable

and another:

http://uncommoncode.wordpress.com/2012/11/07/float-packing-in-shaders-encoding-multiple-components-in-one-float/

and yet another:

decode rgb value to single float without bit-shift in glsl

I've seen others but all of them use the same principle. If you want to encode x and y, they multiply y by some factor and then add x to it. Well this makes since on paper, but I don't understand how in the world it can work when stored to a floating value. Floating values only have 7 significant digits. If you add a big number and a small number, the small number is just truncated and lost. The precision only shows the value of the big number.

Since everyone seems to prescribe the same method, I tried it myself and it did exactly what I thought it would do. When I decoded the numbers, the number that wasn't multiplied turned out as 0.0. It was completely lost in the encoded float.

Here's an example of some MaxScript I tried to test it:

`cp = 256.0 * 256.0`

scaleFac = 16777215

for i = 1 to 20 do (

for j = 1 to 20 do (

x = (i as float / 20.01f) as float;

y = (j as float / 20.01f) as float;

xScaled = x * scaleFac;

yScaled = y * scaleFac;

f = (xScaled + yScaled * cp) as float

print ("x[" + xScaled as string + "] y[" + yScaled as string + "]" + " e[" + f as string + "]")

dy = floor(f / cp)

dx = (f - dy * cp)

print ("x[" + dx as string + "] y[" + dy as string + "]" + " e[" + f as string + "]")

)

)

dx is 0.0 everytime. Can anyone shed some light on this? NOTE: It doesn't matter whether I make cp = 128, 256, 512 or whatever. It still gives me the same types of results.

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

This method works for storing two integers. You're effectively converting your floating point numbers to large integers by multiplying by `scaleFac`

, which is good, but it would be better to make it explicit with `int()`

. Then you need to make sure of two things: `cp`

is greater than the largest number you're working with (`scaleFac`

), and the square of `cp`

is small enough to fit into a floating point number without truncation (about 7 digits for a single precision float).

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**