Conversion error

D

dada

Consider the following function...


/**
***********************************************************************
* COMM_convertFreqIntToDouble
***********************************************************************
*
* \Description: Converts a frequency (integer in Hz) to a
* double in mHz.
*
* \Parameters: in int freqHz - the frequency in Hz
*
* \Returns: double - the representation(in mHz) of the frequency as
a double
*
* \Limitations:
*
***********************************************************************
*/

double COMM_convertFreqIntToDouble ( UINT32 freqHz )
{
double temp = freqHz / 1000.0 / 1000.0 ;
int tempint ;

/* Convert it back and see if they match ! */
tempint = (int) ( temp * 1000 * 1000 ) ;
if ( freqHz != tempint )
{
LOGMSG ( "WARNING", __FUNCTION__,"No Match",
"%d != %d", (unsigned int) freqHz, tempint ) ;
}

return ( temp ) ;
}


LOGMSG is a macro that performs some formatting and writes a message to
the console.

When this functin is called with
130075000
tempint = 130074999

Which causes the warning to be issued.
As I write this I see that I should be debugging and looking at the
double to see if it did indeed convert correctly...

Well, I'll ask my question anyways...
Is the difference being introduced in the conversion TO double or FROM
double, and, is there a better way to perform this operation ?

Thanks !
Joe
 
D

dada

dada said:
Consider the following function...


/**
***********************************************************************
* COMM_convertFreqIntToDouble
***********************************************************************
*
* \Description: Converts a frequency (integer in Hz) to a
* double in mHz.
*
* \Parameters: in int freqHz - the frequency in Hz
*
* \Returns: double - the representation(in mHz) of the frequency as
a double
*
* \Limitations:
*
***********************************************************************
*/

double COMM_convertFreqIntToDouble ( UINT32 freqHz )
{
double temp = freqHz / 1000.0 / 1000.0 ;
int tempint ;

Is this check even necessary ? Should the above work correctly ?
This check is in here because in the past we had seen different values
than we expected and we were attempting to try and capture where the
error was introduced
Thanks !
 
R

Richard Heathfield

dada said:
Consider the following function...

130075000 / 1000000.0 is 130.075 - which we must try to store in
computer memory, which is made up of bits. Bits suggest a binary
representation. Representing the integer part (130) in binary is easy
enough - it's 10000010. But 0.075 is a touch harder:

0.1 = 1/2 = 0.5 - too large
0.01 = 1/4 = 0.25 - too large
0.001 = 1/8 = 0.125 - too large
0.0001 = 1/16 = 0.0625 - too small
0.00011 = 3/32 = 0.09375 - too large
0.000101 = 5/64 = 0.078125 - too large
0.0001001 = 9/128 = 0.0703125 - too small
0.00010011 = 19/256 = 0.07421875 - too small
0.000100111 = 39/512 = 0.076171875 - too large
0.0001001101 = 77/1024 = 0.0751953125 - too large
0.00010011001 = 153/2048 = 0.07470703125 - too small
0.000100110011 = 307/4096 = 0.074951171875 - too small
0.0001001100111 = 615/8192 = 0.0750732421875 - too large
0.00010011001101 = 1229/16384 = 0.07501220703125 - too large
0.000100110011001 = 2457/32768 = 0.074981689453125 - too small
0.0001001100110011 = 4915/65536 = 0.0749969482421875 - too small

How many bits do you think we will need before we get exactly 0.075?
 
A

August Karlstrom

dada skrev:
Consider the following function... [...]
double COMM_convertFreqIntToDouble ( UINT32 freqHz )
[...]

You don't need a function for such a trivial thing as dividing a number
by 1000000. It hides no complexity and it makes the program bigger and
less efficient.


August
 
M

Mark McIntyre

When this functin is called with
130075000
tempint = 130074999

*sigh*

Do a websearch for "Goldberg computer floating point" (without the
quotes).
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
A

Army1987

Consider the following function...


/**
***********************************************************************
* COMM_convertFreqIntToDouble
***********************************************************************
*
* \Description: Converts a frequency (integer in Hz) to a
* double in mHz.
*
* \Parameters: in int freqHz - the frequency in Hz
*
* \Returns: double - the representation(in mHz) of the frequency as
a double
*
* \Limitations:
*
***********************************************************************
*/

double COMM_convertFreqIntToDouble ( UINT32 freqHz )
{
double temp = freqHz / 1000.0 / 1000.0 ;
int tempint ;

/* Convert it back and see if they match ! */
tempint = (int) ( temp * 1000 * 1000 ) ;
if ( freqHz != tempint )
{
LOGMSG ( "WARNING", __FUNCTION__,"No Match",
"%d != %d", (unsigned int) freqHz, tempint ) ;
}

return ( temp ) ;
}


LOGMSG is a macro that performs some formatting and writes a message to
the console.

When this functin is called with
130075000
tempint = 130074999

Which causes the warning to be issued.
As I write this I see that I should be debugging and looking at the
double to see if it did indeed convert correctly...
[snip]
Ever heard 'bout rounding errors?
What's wrong with just freqHz / 1e6?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top