Click to See Complete Forum and Search --> : How accurate will this be....
JamesSchumacher
August 2nd, 2002, 01:38 AM
float CompressDwordToFloat(unsigned long);
unsigned long DecompressDwordFromFloat(float lfValue);
float CompressDwordToFloat(unsigned long dwValue) throw()
{
double lfTemp = (double)dwValue / 16777216;
return static_cast<float>(lfTemp);
}
unsigned long DecompressDwordFromFloat(float lfValue) throw()
{
double lfTemp = lfValue;
lfTemp *= 16777216;
unsigned long dwTemp = static_cast<unsigned long>(lfTemp);
if (lfTemp - (double)dwTemp > 0.5)
{
++dwTemp;
}
return dwTemp;
}
Every value I test works. Are there any problems with this? Since every value I've tested 'decompressed' correctly, I don't see why it would have any troubles. I wish to cut a buffer 'in half' and then compress it normally with zlib or other compression method.
cup
August 2nd, 2002, 06:45 AM
Nothing wrong with it except what is the point? A dword (unsigned long) is the same size as a float - on both 16 and 32 bit machines, they are both 4 bytes in size. You are not really saving anything in size.
dude_1967
August 2nd, 2002, 07:52 AM
I think that the developer wants to convert DWORD to float and is asking if there can be any negative side-effects such as possible loss of precision. In fact, I do not know the answer.
Can DWORD be converted to float without any loss of precision for the entire range which extends from 0 --> 4,294,967,295.
I do not think that it is possible to convert:
DWORD of 4,294,967,295 = 0xFFFFFFFF to float since the float (also with only 4 byte) requires additional space for the exponent and sign.
James, you should look at the standard IEEE 754 format for floating point numbers. The link as well as additional information can be found at this previous post:
http://www.codeguru.com/forum/showthread.php?s=&threadid=191536
Perhaps double might be a safer bet.
Chris.
:)
JamesSchumacher
August 2nd, 2002, 11:28 AM
Thanks for the link. But I think you missed something...
The highest value for my formula will be 255.999999999.
The integer part will be stored easily in the float, question is can the remainder with this formula be correct. I believe it works fine for any value, but I will check into the format.
Thanks.
And yes, I want 32bits down to 16bits.
And the entire reason I want to do so, is a lossless audio compression method. If it works, then I can start with 50% compression to start with, and compress it down farther than that.
JamesSchumacher
August 2nd, 2002, 12:03 PM
I did finish the encoder today (right now only uses this method), I will write the decoder to decode back to wav later today and see if the resultant wave is the same as the source.
Attaching the encoder to this post.
Lightweight - 48.0 KB (No MFC, :D Win32 API app) - just zipped the compiled *.exe. Would be smaller if I used the '#pragma comment(linker,"/OPT:NOWIN98")' trick to make the linker align on 512 byte boundaries. :D
As far as playing goes, I'll write a plugin for WinAmp. :D
(Advice: for small apps with no msvcrt.dll dependencies, write Win32 apps that don't use any CRT functions and have the linker use single threaded crt library. Only thing that will be linked in in _WinMainCRTStartup. :p Just remember not to call any CRT functions, especially in worker threads.)
dude_1967
August 2nd, 2002, 03:25 PM
Hi James,
Now I get the point of the question. Your rounding correction looks OK. One more piece of information. A lot of developers use a simple technique when converting from some floating point type to some integer type.
Many times, you want the resulting integer always to round up. Your sample code has a rounding correction:
static_cast<"some int type">(N.5000000 --> N.9999999) should be N, assuming N positive.
Then in "DecompressDwordFromFloat" you might consider writing a bit more concisely. Maybe using an inline function in some header for speed considerations.
inline unsigned long DecompressDwordFromFloat(float lfValue) throw()
{
return static_cast<unsigned long>(0.5 + lfValue * 16777216.0);
}
Chris
:)
JamesSchumacher
August 2nd, 2002, 04:35 PM
FORGET IT....
FAILED TO COMPUTE == FLOAT == 32 BITS and DOUBLE == 64 bits.
Man I'm tired, I thought sizeof(float) == 16 bits.
I swear I read:
float == 16 bits
single = 32 bits
double = 64 bits
But I guess now that VC++ doesn't have single, and float is mapped to 32bits? Might be because VC++ maps long double (80 bits) to double (64 bits). So you don't have the long double type.
:confused: To heck if I know.
Just try it:
assert(sizeof(long double) == 10); // exception will be thrown, long double maps to double - size == 8
(OFF TOPIC: I just love VC++ :rolleyes: Should've spent money on Codewarrior. Better yet, just move to Linux. :D )
dude_1967
August 5th, 2002, 03:50 AM
Indeed James,
The various topics relating to floating pöoint precision can get quite confusing and cause frustration.
Here is an attempt to clear up some of the stuff:
The standardized format for floating point numbers is called IEEE 754 (http://http.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF).
The specification mandates that single precision floating point (native type "float" in C and C++) have a size of 32 bits (4 bytes) resulting in 6-9 decimal digits of precision.
The specification mandates that double precision floating point (native type "double" in C and C++) have a size of 64 bits (8 bytes) resulting in 15-17 decimal digits of precision.
Support for long double (10 bytes, 19-21 decimal digits of precision) is optional. The sad thing about developer studio is that the native type long double exists for the compiler, but is not supported: The data type long double for developer studio is double. In my opinion this is improper.
The GNU compiler collection (GCC) C and C++ compilers do support full 10 byte long double as well as the implementation of IEEE754.
Good luck.
Chris.
:)
JamesSchumacher
August 5th, 2002, 01:43 PM
compilers for Windows, but is there any IDE that will work with them?
(That is until I can install Linux on this machine.)
cup
August 5th, 2002, 07:04 PM
Try Dev-C++ from http://www.bloodshed.net/.
Alternatively, there is lcc-win32, which isn't gcc but is free. http://www.cs.virginia.edu/~lcc-win32/
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.