Discussion:
"PORTING C" > Why float gets rounded off ???
(too old to reply)
Robby
2010-02-01 16:44:01 UTC
Permalink
Hello,

Okay, this question has to do alot with my previous post that I posted
yesterday. I don't understand why the answer (of type float) gets rounded off
the the lower number and looses its precision after the decimal. Here is the
code again.

====================================main.c
#include <stdio.h>

#define SYS_OSC 10500000 // Current system clock 10.5 MHZ
#define MICRO_SEC 0.000001 // 1 micro second
#define OSC_PERIOD (1.0/SYS_OSC) // 1 second divide by system clock
#define DELAY_LOOP_IC 7.0 // 7 instructions per while loop iteration (delay)
#define RATIO(a,b,c) (a/(b*c)) // a,b,c parameters

int main()
{
unsigned int us_delay=16;
float x;

x = (float)RATIO((float)MICRO_SEC, (float)OSC_PERIOD, (float)DELAY_LOOP_IC)
* (float)us_delay;

return 0;
}
====================================

In response to x, the representauon of the RATIO macro multiplied by
"us_delay" should be the following calculation:

24.06015038 = (0.000001 / (0.000000095/7.0)) * 16

but VC gets rid of the numbers after the decimal and gives:

24.000000 = (0.000001 / (0.000000095/7.0)) * 16

The thing is that I require x to be with numbers after the decimal... like
this:

24.06015038

I have typed casted all the values, I have even set the 7 as a 7.0 and I
fixed the divide by zero mistake which was pointed out in my previous post...
and I made "x" as a floating type and us_delay is typ casted too to a
float!!!!

I guess I am still missing something... ? Help!
--
Best regards
Roberto
Bo Persson
2010-02-01 17:31:48 UTC
Permalink
Post by Robby
Hello,
Okay, this question has to do alot with my previous post that I
posted yesterday. I don't understand why the answer (of type float)
gets rounded off the the lower number and looses its precision
after the decimal. Here is the code again.
====================================main.c
#include <stdio.h>
#define SYS_OSC 10500000 // Current system clock 10.5 MHZ
#define MICRO_SEC 0.000001 // 1 micro second
#define OSC_PERIOD (1.0/SYS_OSC) // 1 second divide by system clock
#define DELAY_LOOP_IC 7.0 // 7 instructions per while loop
iteration (delay) #define RATIO(a,b,c) (a/(b*c)) // a,b,c parameters
int main()
{
unsigned int us_delay=16;
float x;
x = (float)RATIO((float)MICRO_SEC, (float)OSC_PERIOD,
(float)DELAY_LOOP_IC) * (float)us_delay;
return 0;
}
====================================
In response to x, the representauon of the RATIO macro multiplied by
24.06015038 = (0.000001 / (0.000000095/7.0)) * 16
24.000000 = (0.000001 / (0.000000095/7.0)) * 16
The thing is that I require x to be with numbers after the
24.06015038
I have typed casted all the values, I have even set the 7 as a 7.0
and I fixed the divide by zero mistake which was pointed out in my
previous post... and I made "x" as a floating type and us_delay is
typ casted too to a float!!!!
I guess I am still missing something... ? Help!
You are probably missing that 1.0/1050000 isnt 0.000000095 but more
like 9.52381e-8

Floating point, not fixed point!


Bo Persson
Alexh
2010-02-01 18:13:49 UTC
Permalink
Post by Bo Persson
Post by Robby
Hello,
Okay, this question has to do alot with my previous post that I
posted yesterday. I don't understand why the answer (of type float)
gets rounded off the the lower number and looses its precision
after the decimal. Here is the code again.
====================================main.c
#include <stdio.h>
#define SYS_OSC 10500000     // Current system clock 10.5 MHZ
#define MICRO_SEC 0.000001     // 1 micro second
#define OSC_PERIOD (1.0/SYS_OSC)  // 1 second divide by system clock
#define DELAY_LOOP_IC  7.0 // 7 instructions per while loop
iteration (delay) #define RATIO(a,b,c) (a/(b*c)) // a,b,c parameters
int main()
{
unsigned int us_delay=16;
float x;
x = (float)RATIO((float)MICRO_SEC, (float)OSC_PERIOD,
(float)DELAY_LOOP_IC) * (float)us_delay;
return 0;
}
====================================
In response to x, the representauon of the RATIO macro multiplied by
24.06015038 = (0.000001 / (0.000000095/7.0))  * 16
24.000000 =  (0.000001 / (0.000000095/7.0))  * 16
The thing is that I require x to be with numbers after the
24.06015038
I have typed casted all the values, I have even set the 7 as a 7.0
and I fixed the divide by zero mistake which was pointed out in my
previous post... and I made "x" as a floating type and us_delay is
typ casted too to a float!!!!
I guess I am still missing something... ? Help!
You are probably missing that 1.0/1050000 isnt 0.000000095 but more
like 9.52381e-8
Floating point, not fixed point!
Bo Persson- Hide quoted text -
- Show quoted text -
This is actually a fairly complex question and has to do with the way
floating point #'s are represented in HW.

Here is an excellent article on the topic -

http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
Robby
2010-02-01 19:21:02 UTC
Permalink
Hi Bo and Alexh,
Post by Alexh
http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
I quickly skimmed over the article and yes, it makes sence that in certain
circumsatnces a computer can't really give very precise value slices after
the decimal point since it can fall in a grey area as stipulated in your
article:

"example, ½1 + ½2 + ½3 + … + ½23). This means that in the range of floating
point numbers there are gaps; "

and further in the article it says:

" for example, imagine that .37 is represented as .369999998 rather than
.370000004."

But my problem is the opposite, I do want the 0.369999998 acurracy .... ???

I wouldn't even know where to start to solve this problem ... C language wise!

This sort of stuff would require me some time to fully study it and then see
if it applies to what I am trying to do, and for this reason, I think I will
content myself with the 24.000000. :-)

But hey! I still thank everyone very much for your help and its reassuring
that there is an explanation behind this. In anycase this is the sort of
stuff that I will leisurely browse on a Sunday afternoon given the time.

Thank you all for your replies... very appreciated!

Sincere regards
Rob
Alexh
2010-02-01 19:35:27 UTC
Permalink
Post by Robby
Hi Bo and Alexh,
Post by Alexh
http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
I quickly skimmed over the article and yes, it makes sence that in certain
circumsatnces a computer can't really give very precise value slices after
the decimal point since it can fall in a grey area as stipulated in your
"example, ½1 + ½2 + ½3 + … + ½23). This means that in the range of floating
point numbers there are gaps; "
" for example, imagine that .37 is represented as .369999998 rather than
.370000004."
But my problem is the opposite, I do want the 0.369999998 acurracy ....  ???
I wouldn't even know where to start to solve this problem ... C language wise!
This sort of stuff would require me some time to fully study it and then see
if it applies to what I am trying to do, and for this reason, I think I will
content myself with the 24.000000.   :-)
But hey! I still thank everyone very much for your help and its reassuring
that there is an explanation behind this. In anycase this is the sort of
stuff that I will leisurely browse on a Sunday afternoon given the time.
Thank you all for your replies... very appreciated!
Sincere regards
Rob
Rob,

If you set a double to 0.000000095 and see what it actually comes up
as in your debugger you will see the problem. I have even run into
problems where .00001 is actually represented by 0.00098 (or similar).
I forget if MS C++ allows for more accurate floating point variable
definitions like they do with ints (i.e. 64 bit ints) but you might
check on this.
Alexh
2010-02-01 19:42:30 UTC
Permalink
Post by Alexh
Post by Robby
Hi Bo and Alexh,
Post by Alexh
http://www.theregister.co.uk/2006/08/12/floating_point_approximation/
I quickly skimmed over the article and yes, it makes sence that in certain
circumsatnces a computer can't really give very precise value slices after
the decimal point since it can fall in a grey area as stipulated in your
"example, ½1 + ½2 + ½3 + … + ½23). This means that in the range of floating
point numbers there are gaps; "
" for example, imagine that .37 is represented as .369999998 rather than
.370000004."
But my problem is the opposite, I do want the 0.369999998 acurracy ....  ???
I wouldn't even know where to start to solve this problem ... C language wise!
This sort of stuff would require me some time to fully study it and then see
if it applies to what I am trying to do, and for this reason, I think I will
content myself with the 24.000000.   :-)
But hey! I still thank everyone very much for your help and its reassuring
that there is an explanation behind this. In anycase this is the sort of
stuff that I will leisurely browse on a Sunday afternoon given the time.
Thank you all for your replies... very appreciated!
Sincere regards
Rob
Rob,
If you set a double to 0.000000095 and see what it actually comes up
as in your debugger you will see the problem. I have even run into
problems where .00001 is actually represented by 0.00098 (or similar).
I forget if MS C++ allows for more accurate floating point variable
definitions like they do with ints (i.e. 64 bit ints) but you might
check on this.- Hide quoted text -
- Show quoted text -
Another question I would ask is - how does MS implement the scientific
calculator function?
Robby
2010-02-01 21:04:01 UTC
Permalink
Post by Alexh
If you set a double to 0.000000095 and see what it actually comes up
as in your debugger you will see the problem. I have even run into
problems where .00001 is actually represented by 0.00098 (or similar).
I forget if MS C++ allows for more accurate floating point variable
definitions like they do with ints (i.e. 64 bit ints) but you might
check on this.
Hi Alex,

I tried it but I don't know if this is what you meant:

==============================main.c
#include <stdio.h>

#define SYS_OSC 10500000 // Current system clock 10.5 MHZ
#define MICRO_SEC 0.000001 // 1 micro second
#define OSC_PERIOD (1.0/SYS_OSC) // 1 second divide by system clock
#define DELAY_LOOP_IC 7.0 // 7 instructions per while loop iteration
(delay)
#define RATIO(a,b,c) (a/(b*c)) // a,b,c parameters

int main()
{
unsigned int us_delay=16;
float x;
double d;

d = (double)OSC_PERIOD;

x = (float)RATIO((float)MICRO_SEC, d, (float)DELAY_LOOP_IC); // *
(float)us_delay;

return 0;
}
====================================

d gives a very long number floating point number. I always thought that a
double was a very long integer! In anycase, the above doesn't keep the
numbers after the decimal such as:

24.06015038

Discouraged!

Rob
David Wilkinson
2010-02-01 19:31:53 UTC
Permalink
Post by Robby
Hello,
Okay, this question has to do alot with my previous post that I posted
yesterday. I don't understand why the answer (of type float) gets rounded off
the the lower number and looses its precision after the decimal. Here is the
code again.
====================================main.c
#include <stdio.h>
#define SYS_OSC 10500000 // Current system clock 10.5 MHZ
#define MICRO_SEC 0.000001 // 1 micro second
#define OSC_PERIOD (1.0/SYS_OSC) // 1 second divide by system clock
#define DELAY_LOOP_IC 7.0 // 7 instructions per while loop iteration (delay)
#define RATIO(a,b,c) (a/(b*c)) // a,b,c parameters
int main()
{
unsigned int us_delay=16;
float x;
x = (float)RATIO((float)MICRO_SEC, (float)OSC_PERIOD, (float)DELAY_LOOP_IC)
* (float)us_delay;
return 0;
}
====================================
In response to x, the representauon of the RATIO macro multiplied by
24.06015038 = (0.000001 / (0.000000095/7.0)) * 16
24.000000 = (0.000001 / (0.000000095/7.0)) * 16
The thing is that I require x to be with numbers after the decimal... like
24.06015038
I have typed casted all the values, I have even set the 7 as a 7.0 and I
fixed the divide by zero mistake which was pointed out in my previous post...
and I made "x" as a floating type and us_delay is typ casted too to a
float!!!!
I guess I am still missing something... ? Help!
The (unrounded) calculation you are doing is

x = (0.000001 * 10500000 * 16)/7

which is exactly 24. This happens because 7 divides exactly into 105.
--
David Wilkinson
Visual C++ MVP
Robby
2010-02-01 20:58:01 UTC
Permalink
Post by David Wilkinson
The (unrounded) calculation you are doing is
x = (0.000001 * 10500000 * 16)/7
which is exactly 24. This happens because 7 divides exactly into 105.
Hi David,
Post by David Wilkinson
24.06015038 = (0.000001 / (0.000000095/7.0)) * 16
was supposed to be:

24.06015038 = (0.000001 / (0.000000095*7.0)) * 16

I appolagize!

If we do this on our calculators, this gives:

24.06015038

And its driving me up a wall as to why I can't do this in C.
--
Best regards
Roberto
Igor Tandetnik
2010-02-01 21:06:12 UTC
Permalink
Post by Robby
24.06015038 = (0.000001 / (0.000000095*7.0)) * 16
I appolagize!
24.06015038
But 1.0/10500000 is _not_ 0.000000095. Why do you insist on plugging 0.000000095 into your formula? Where did you get this number from?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Robby
2010-02-01 22:12:09 UTC
Permalink
Post by Robby
24.06015038 = (0.000001 / (0.000000095*7.0)) * 16
I appolagize!
24.06015038
But 1.0/10500000 is _not_ 0.000000095. Why do you insist on plugging >0.000000095 into your formula? Where did you get this number from?
Why I insist, you ask. Because I should of stayed in bed today, it would of
been more productive! :-)

See my last post which explains the stupidity that goes on in this office. I
am so mad at myself... I wasted a good part of the day on this... what a burn!

Sorry for this question. A lesson that I learned here!

Regards
Rob

Robby
2010-02-01 22:01:02 UTC
Permalink
I appolagize for this post, it was my fault, I did not enter the full numbers
in my calculator. 1/10500000 does not equal 0.000000095.

My calculator (or most calculators) never show:

9.5238095238095238095238095238095e-8

it only showed:

0.000000095

After doing this: 1/10500000 on my calculator, I got fed up of it and just
memorized
0.000000095 in my mind forgetting that there was more numbers after the
decimal.
Post by Bo Persson
You are probably missing that 1.0/1050000 isnt 0.000000095 but more
like 9.52381e-8
Thanks BO.

I am so out of it!

Thank oyu all for your help!
--
Best regards
Roberto
Continue reading on narkive:
Loading...