Skip to main content
gamedev.net
🔒 Locked

Disecting a float

Started by Jiia 2 replies 400+ views
Original Post
Jiia
Jiia
I'm unsure of the exact terms, so I'll try to explain it. Let's say I have a float variable "f", in which I want to store the values of 2 floats.
f = 1567.0555;
float x,y;
int top = (int) f;
x = top / 1000.0;
y = (f - top) * 10.0;
I want to do this so that I can send less data to the vertex shader for texture coordinates. It will cut the 16 floats I need to send down to 8. I have three questions if anyone has the time [smile] First, is this an ugly hack or what? Perhaps a better way to send the data? I don't think vertex shaders support 16 bit variables. Am I wrong? Second, does anyone know the maximum values of the numbers of each side of the decimal point? Both sides have the same range? Each side depends on how much data the other side uses? This is how floats work, right? The higher x is, the less precision y can use? Last, anyone know of a better way to pull the data apart inside the shader besides casting to an int? I'm using HLSL in DirectX 9c, so I'm not sure what is happening behind the scenes in asm. Guess this last one belongs in another forum. x = upper(f) / 1000; y = lower(f) * 10; Something magical such as that? Hehe [smile] I appreciate any suggestions or advice
paulecoyote
paulecoyote
[google] provides answers...

http://richardbowles.tripod.com/durham/comparch/binary.htm

... though I guess you have to know what question to ask?

Hope that helps anyway.
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
Emmanuel Deloget
Emmanuel Deloget
Quote:
Original post by Jiia
I'm unsure of the exact terms, so I'll try to explain it. Let's say I have a float variable "f", in which I want to store the values of 2 floats.
f = 1567.0555;float x,y;int top = (int) f;x = top / 1000.0;y = (f - top) * 10.0;

I want to do this so that I can send less data to the vertex shader for texture coordinates. It will cut the 16 floats I need to send down to 8. I have three questions if anyone has the time [smile]

First, is this an ugly hack or what? Perhaps a better way to send the data? I don't think vertex shaders support 16 bit variables. Am I wrong?


This msdn entry should answer your second question. DX9 has support for 16 bit floats. Of course, your GPU may not support them - I don't remember the conditions.

As for your first question, your hack seems strange - and I don't really understand your point here. What are you trying to do? If you are trying to pack N numbers into only one, then you have to possibilities:

1) pack numbers as a single number using different ranges: n = n1*k*k + n2 * h + n3. It assumes that your numbers are in the range [0..k]. If it is not the case then you won't be able to store then that way.

2) pack numbers at a known position: n = (n1 << (2*k)) | (n2 << k) | n3. This can be done is your number fits on k bits (you manage then as you want). This is the solution the DX guys implemented (hence the FLOAT16 data type). Take care: if you want to store floating points, you'll have to choose how many bits you'll use as the mantissa, how many will be the exponent, you'll have to do the math and so on. Not easy.

Quote:
Original post by Jiia
Second, does anyone know the maximum values of the numbers of each side of the decimal point? Both sides have the same range? Each side depends on how much data the other side uses? This is how floats work, right? The higher x is, the less precision y can use?

What is x? if this is the float value, then yes: the hiher it is, the less precision you can use. This is because the precision of the mantissa is limited. The exponent does not give you any more information (except: where do I put the comma in this number). The more bits you give to the mantissa, the more "precise " your number is.

Quote:
Original post by Jiia
Last, anyone know of a better way to pull the data apart inside the shader besides casting to an int? I'm using HLSL in DirectX 9c, so I'm not sure what is happening behind the scenes in asm. Guess this last one belongs in another forum. x = upper(f) / 1000; y = lower(f) * 10; Something magical such as that?

Nothing particular happens in asm. IMHO HLSL is low level enough to be mapped to math operations using your own mind. If you want to see what is the generated asm code then I believe you can use some special flags in the shader compiler to get it.
Beside that: there is nothing magic in math :)

HTH,
Promit
Promit
Cg allows the half data type (float16) but in most profiles it appears to be implemented as a float anyway, including vs 1.1 and arbvp1.

As for floats, they are stored:
[1 sign bit][8 exponent bits][23 mantissa bits]

The mantissa is normalized, and the xponent is base 2, biased by 128. So the number value is:
1.mantissa * 2^(exp - 128)
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.