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
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;