View previous topic :: View next topic |
Author |
Message |
miro
Joined: 15 Jan 2011 Posts: 62
|
COS SIN broken? |
Posted: Sun Jul 05, 2015 8:18 am |
|
|
May be I am doing something wrong, but for these arguments I get following COS values (pcwhd 5.048 and others most probably):
Code: | rad COS(rad)
3.7129E+02 8.3146E-01
3.7738E+02 9.2388E-01
3.8347E+02 9.8078E-01
3.8955E+02 1.0000E+00
3.9564E+02 9.8078E-01
4.0173E+02 9.2387E-01
4.0781E+02 -2.8387E+19 <<< from here a mess!!
4.1390E+02 -2.8248E+19
4.1999E+02 -2.8110E+19
4.2607E+02 -2.7973E+19
4.3216E+02 -2.7836E+19
4.3825E+02 2.9951E+19
4.4433E+02 2.9806E+19
4.5042E+02 2.9661E+19 |
Similar with SIN.
Is the COS/SIN broken??
M.
Last edited by miro on Sun Jul 05, 2015 9:30 am; edited 1 time in total |
|
|
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Sun Jul 05, 2015 9:26 am |
|
|
It seems the trick with getting COS into radian quadrants is quite limited in its scope - see the math.h (lines 1188-1197):
Code: |
quad = (unsigned int8)(x * PI_DIV_BY_TWO_INV); // quadrant
frac = (x * PI_DIV_BY_TWO_INV) - quad; // fractional part of input |
With unsigned int8 it will crash for COS arguments where
(x * PI_DIV_BY_TWO_INV) > 256
for example for above 407.81
PS: thus the Ex_FFT will not work properly for more than 32 points FFT length. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jul 05, 2015 10:48 am |
|
|
This is a 'read the manual' one. Look at the entry for sin:
Quote: |
val = sin (rad)
rad is a float representing an angle in Radians -2pi to 2pi.
|
Like most such algorithms an approximation is used, and the one here is _only_ 'warranted to work over the range -2pi to 2pi.
If you want o handle angles larger than this, then you need to handle reducing to the legal range yourself.
In fact K&R, has the same limits shown. |
|
|
miro
Joined: 15 Jan 2011 Posts: 62
|
|
Posted: Sun Jul 05, 2015 11:07 am |
|
|
Reducing the range is matter of "highest precision", not stopping to work
The ccs compiler is the only one I know where cos/sin stop working with arguments larger a few hundreds of radians They should fix that, of course.
PS: They do the range reduction, but a wrong way as it returns nonsense with some arguments. The cos and sin shall work over any real arguments. The K&R is not much related to that issue - it is a library issue. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jul 05, 2015 12:06 pm |
|
|
CCS C, is _not_ alone in this. Just use fmod.
Instead of sin(val), use sin(fmod(val,2*PI))
This is standard practice in C. A lot of C's on things like the PC don't need this (since the FPU automatically does this for trig functions), but for most C's you do have to do this.
CCS does not do this as standard, since it adds bulk, and slows the code. It's not needed if the range of the incoming angle is limited elsewhere. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sun Jul 05, 2015 2:53 pm |
|
|
gee, guess I'm 'old' but having a PIC do high powered math just seems 'wrong' to me !
I am impressed though with what some guys get them to do though !!!
Jay |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Jul 05, 2015 4:06 pm |
|
|
I feel the same way. The things people try to do with a PIC
makes we shake my head. So many more capable processors
out there without the PICs limitations. I suspect many of
these are school projects where the instructor made an assignment . _________________ Google and Forum Search are some of your best tools!!!! |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sun Jul 05, 2015 4:22 pm |
|
|
Just out of curiosity:
Where /how do you READ the angle you will compute SIN/COS from
and
WHAT do you plan to DO with the float result you seek?
I'm puzzled at why you feel you need to do this in the PIC in the first place. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sun Jul 05, 2015 11:21 pm |
|
|
Seriously though this is _not_ a PIC limitation.
Though you have not met other sin functions that will only accept angles in the +/- 2*pi range, this is actually part of the _specification_ of the C sin function, and is common on C's.
There is no loss of accuracy involved, you just need to work in the range of abilities of the function. |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Mon Jul 06, 2015 3:14 am |
|
|
Just this week I needed to convert the readings of an accelerometer which measures gravity into angles. No big deal for a PIC but it did require adjusting the parameters to the range of the function and then adjusting the results to degrees. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Jul 06, 2015 5:02 am |
|
|
Quote: | PS: thus the Ex_FFT will not work properly for more than 32 points FFT length. |
Why do you think this, Miro? I can see no reason for it to be the case, and, specifically, no reason for the inputs to sin() of cos() in the example ever to be anywhere near the values you cite as giving problems.
In most sin and cos computation algorithms, the core uses an approximation, generally based on Chebyshev polymonials, that's only valid for a single quadrant (pi/2) range, but folded, just as the CCS version appears to do, to the minimum guaranteed range; +/-2Pi in the case of C. Anything extra is non-repeatable/non-transportable and should not be used, and certainly not relied on, or, indeed, complained about. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Jul 06, 2015 9:04 am |
|
|
Spot on.
I think he is being 'misled' because on PC's, the hardware FPU, _does_ automatically normalise values outside this range to the required range. |
|
|
|