We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello, I have a problem with the accuracy of the result when I divide 2 float values. This is the line in my source Code:
dds_word.long_dds = 2.147483648E16 / 7.1312E7
double and float are the same thing in C51. I seem to recall float gives something like 6 or 7 digits of precision so you'll probably have to roll your own solution to do better. Stefan
thx for answer Stefan, but how can I roll my soloution to get more precision? I have no idea. Jan
Well, as some people like to say: "if you have to ask, you're probably not up to it." Implementing your own floating point arithmetics packages is a huge effort. Are you sure you really need more than 6 digits? Are you really handling data that have an accuracy on other order of 1 ppm? And if so, why would you use a cheap 8051 to handle it --- sensors of that quality cost enough that the price of a higher-performance chip to control them would never be noticed.
I need the value load a DDS and there I need an accuracy of 1Hz. I use the 8051 to handle it because the layout is ready. I have not designed it and I'm sure that I had taken a 16 Bit CPU.
Hmm... is that value you're trying to compute actually a integer, by any chance? If so, maybe you should just ditch the whole floating point stuff and use unsigned longs (after pre-dividing both constants by 1e7, e.g., they're both in the range of unsigned long). Or hard-code the actual result you wanted instead of dividing through magic constants in the source code.
Yes it is an integer value which I try to compute. The problem when I divide the values is the following. The value 2.147483648E16 is fix but the second value is variable from 70700000, 70700001, 70700002 .....124999999, 125000000. When I pre-divide this value then the value 124999999 looks like this 124. Then my problem is much bigger because many results are the same. Jan
The following URL http://docs.sun.com/source/806-3568/ncg_goldberg.html links to an article titled, "What Every Computer Scientist Should Know About Floating-Point Arithmetic." This article addresses most of the floating-point questions posed on this forum. Jon
That looks like you actually need arbitrary precision arithmetics A rough outline: recall how you learned to do multiplication and division on multi-digit numbers in elementary school. Apply same principles to very large numbers, using bytes or ints instead of decimal digits. Let's say we use unsigned 16-bit ints for "digits". That makes your dividend a 4-digit number, and all your divisors 2-digit numbers. So you would divide pairwise, compute remainders and accumulate results. There are multiple precision arithmetics packages out there that help with this --- I'm not aware of any working on 8051s though.
You will find a set of 64-bit functions using only 32-bit variables here: ftp.embedded.com/.../crenshaw98.txt
I have solved the problem. Here is the solution which I use. I hope I will get no problem with the timing.
unsigned long test_value; unsigned int result; unsigned long test_freq; dds_word.long_dds = 0; test_value = 0x04C4B400; for (i=0; i<7; i++) { result = test_value / test_freq; test_value = test_value - (result * test_freq); test_value = test_value << 4; dds_word.long_dds += result; dds_word.long_dds = dds_word.long_dds << 4; } result = test_value / test_freq; dds_word.long_dds += result;