Skip to main content
gamedev.net
🔒 Locked

A short float?

Started by CyberSlag5k Apr 19, 2004 at 4:44 PM 11 replies 1.1k views
Original Post
CyberSlag5k
CyberSlag5k
Is there a way to get a short float? I need a 150x2200 array of floats that are (for the most part) between 10 and -10. Just creating an array of floats that size is simply not possible, so I need an alternative. Thanks When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...
Without order nothing can exist - without chaos nothing can evolve.
BriTeg
BriTeg
Why isn''t it possible? 150 x 2200 x 4bytes = only about 1.3 Meg.
Brianmiserere nostri <font color=#BC
vnillabrent
vnillabrent
If you really need the size and don''t mind sacrificing a little bit of speed, you could use unsigned characters but convert them to floats when needed:

float newval = (float)oldval / 255 * 20 - 10;

255 * 20 could further be optomized too. Fixed point mathematics is also a possibility, but that seems like too much overhead for such a simple problem. Unfortunitly, floats are the smallest true floating point data type.
CyberSlag5k
CyberSlag5k
quote:

Why isn't it possible? 150 x 2200 x 4bytes = only about 1.3 Meg.



Don't know. Anything above about 150x1700 just crashes.

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...

[edited by - CyberSlag5k on April 19, 2004 5:55:21 PM]
Without order nothing can exist - without chaos nothing can evolve.
SiCrane
SiCrane
I''m going to guess you''re trying to allocate it on the stack. Try allocating on the heap (with new or malloc() or whatever your langauge of choice uses).
LousyPhreak
LousyPhreak
dont use static arrays...

allocate them during runtime with "new" and you wont run into such limitations.

also dont forget to release the memory after you used it
http://mitglied.lycos.de/lousyphreak/
BriTeg
BriTeg
quote:
Original post by CyberSlag5k
Don''t know. Anything above about 150x1700 just crashes.



Ah, you''re declaring it on the stack. I think there''s a limit of 1 Meg or so.

Instead, allocate your array on the heap.


float *fred;

fred = new float [150*2200];

...

delete [] fred;



Brianmiserere nostri <font color=#BC
CyberSlag5k
CyberSlag5k
This is why I love you people.

Thanks

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...
Without order nothing can exist - without chaos nothing can evolve.
deks
deks
For numbers in the range [-10..10], you need to represent 21 different integer values, so 5 bits is enough ([0..31]). Then, depending on the precision you need, you could easily use 3 bits for it. If you need more, then use 11 bits (for a total of 16). To store the number, simply do:


integer = floor(v) + 10;
precision = (v - floor(v)) * 2^bits;


and to restore, do:


v = (integer - 10) + (precision / 2^bits);


Then pack integer and precision in 8/16 bits.

Or implement your own FP16 class.

JF

[edited by - deks on April 19, 2004 6:10:33 PM]
CyberSlag5k
CyberSlag5k
Thanks deks. That last one was a bit over my head but I''m going to spend a little time thinking on it.

Also, I can''t seem to do the following:

float *myArray;
myArray = new float[150][2200];

It won''t compile.

If I do myArray = new float[150*2200] it''ll work (as BriTeg suggested), I can compile and I''ll have allocated enough space for my array, butI don''t see how I am to access the object as a 2 dimensional array.

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...
Without order nothing can exist - without chaos nothing can evolve.
BriTeg
BriTeg
Well, you could do this:


float **fred;
int i;

fred = new float * [150];
for(i=0;i<150;i++)
fred[i] = new float[2200];

fred[10][20] = 5.5555f;

for(i=0;i<150;i++)
delete [] fred[i];
delete [] fred;


But then the std::vector people get upset.
Brianmiserere nostri <font color=#BC
CyberSlag5k
CyberSlag5k
Wonderful. Thank you yet again.

When you find yourself in the company of a halfling and an ill-tempered Dragon, remember, you do not have to outrun the Dragon...
Without order nothing can exist - without chaos nothing can evolve.
deks
deks
Also, depending on the precision needed, you can use a 16bit floating point representation... ie 10 bits for the mantissa, 5 for the exponent and 1 for the sign. Here's some code:


struct kfFloat32 // normal IEEE 32bits float

{
tU32 u32Mantissa : 23;
tU32 u32Exponent : 8;
tU32 u32Sign : 1;
};

struct kfFloat16 // DX9 compatible 16bits float

{
tU16 u16Mantissa : 10;
tU16 u16Exponent : 5;
tU16 u16Sign : 1;

kfFloat16(tFloat fValue)
{
*this = fValue;
}

void operator=(tFloat fValue)
{
u16Sign = ((kfFloat32*)&fValue)->u32Sign;
u16Exponent = ((kfFloat32*)&fValue)->u32Exponent - 127 + 15;
Parts.u16Mantissa = min(floor((tFloat)((kfFloat32*)&fValue)->u32Mantissa / 8388608.0f * 1024.0f), (1 << 10) - 1);
}

operator tFloat()
{
kfFloat32 f32Result;
f32Result.u32Sign = u16Sign;
f32Result.u32Exponent = u16Exponent - 15 + 127;
f32Result.u32Mantissa = ktMin<tU32>(floor((tFloat)u16Mantissa / 1024.0f * 8388608.0f), (1 << 23) - 1);
return *(tFloat*)&f32Result
}
};


My code is based on this link. It can still contains bugs, but I use it in several places in my engine so it's minimaly tested in real conditions, and it seems to work fine with DX9 16F render targets.

Hope it helps,
JF



[edited by - deks on April 20, 2004 6:21:18 PM]

Topic Locked

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

Sign in to reply to this topic.