Hello,
I'm working with cw 6.2, and trying do make some trigonometric calculations. The target is a MCF51qe.
For exemple, when I do this:
sin((double)0.86217507327430);
I obtain 0.75926020631887015.
In matlab, the same sinus gives 0.75925986842193.
The difference is not so big, but I have difference for each sin/cos calculation, and the result is used to found the distance between 2 GPS points. The distance is given using an acos function but the argument of the acos is >1, due to precision problems; so it can't be calculated. I'm sure of the formulas I'm using, as I checked with a computer and the problem doesn't appear (argument of acos is always<1).
In cw, I have included this libs:
fp_coldfire_nodiv.a
C_4i_CF_RegABI_MATH_MSL.a
C_4i_CF_RegABI_Runtime.a
I've tried other libs but without success.
Someone has an idea?
Thanks for your help!
Here is the response of the service request:
Dear Guillaume,
You are right, the MCF51QE128 isn't as accurate like the matlab software, the reason is very simple, our mcu doesn't have a multiplication or division unit, therefore there's the need to create software routines (libraries) that implements such instructions. That's the reason why matlab is more accurate, because at matlab all the processing of information occurs at your computer, the MCF51QE isn't as powerful like your computer core, but is cheaper and easier to understand.
For them, the problem is not the library but the MCF51...
Then they are not telling the thruth. MCF51 is as accurate as any other computer in the world. Inaccurate is their sin() routine. Their double precision software mul, add, div etc are fine (I checked that if it matters).
It is not true also that MCF51 doesn't have hardware multiplication. It has. It doesn't have division, but division emulation on Coldfire V1 is pretty fast. Of course slower than with hardware division, but not zilions of times.
I think you need accurate results first, then the execution speed. If you would need speed, you could use single precision of maybe fixed point routines.
I agree with you Kef.
I have re-opened the service request.
I can see I neglected to handle to negative (error case)
if(x < 0.0) { return(MY_DOUBLE_ERROR_IS_INFINITY); }
Or you can use identities to make x = x + 2pi if x < 0
Thanks for your answer Emac.
I will try your sinus function. I also have to check if it is fast enough, as I have to do real time caclulation of GPS position.
If need be, the number of terms can easily be scaled back if you need faster operation at the cost of less accuracy. The current number of terms matched your matlab calculated value but perhaps fewer terms would work as well. Also the constants could be better defined. The source of my numbers and constants was Excell - not known as being the ultimate mathmatical standard.
Good luck!
When I have created the project, to the question:
"select if you want floating point support" I choose "float is ieee64, double is ieee64" .
this includes the foloowing libraries:
C_4i_CF_RegABI_MATH_MSL.a, C++_4i_CF_RegABI_MATH_MSL.a, Cpp_4i_CF_RegABI_Runtime.a
If I choose "no" to the question, the following libraries are included:
C_4i_CF_RegABI_MSL.a, C++_4i_CF_RegABI_MSL.a, Cpp_4i_CF_RegABI_Runtime.a
Nobody has an idea?
If I compute the sinus in single precision, there is always a different between mcu and matlab result.
Thanks
Something is wrong with CW library, you should do a service request. If you can't wait for bugfixes, then you may try using third party math functions. Something like cephes lib at www.netlib.org should be more precise.