Post Reply 
New firmware for the Swissmicros DM15L
10-10-2024, 06:18 AM
Post: #105
RE: New firmware for the Swissmicros DM15L
(10-10-2024 05:11 AM)jebedeo Wrote:  However, I am uncomfortable with having a sin that does not return 0 when the input is 180 degrees.

The problem comes from the fact that the sin() from the math library for c is implemented with rads. Which, as said a couple of posts ago, is not representable in floating point so sin(pi) should not return 0. Fair enough, but that means that unless I play some dirty trick in converting radians to degrees, sin(180) won't return 0.
SIN(180°) not returning 0 is indeed, a sin ;-)
You have to do range reduction (to x<=45°) in degrees before converting to radians..
I see that the post about this doesn't show it anymore, so in high-level pseudocode:
For SIN and COS:

real function SINCOSDEG(real x, boolean fSIN)

  boolean fNEG := FALSE;

/* this part IS needed, because eg -4/3 360 MOD loses digits */
  if x < 0
  then do
    x := -x;
    if fSIN then fNEG := TRUE;    -- SIN(-x) = -SIN(x) and COS(-x) = COS(x)
  end;

  x := MOD(x,360);                -- [0 360[

  if x >= 180
  then do
    x := x - 180;                 -- SIN(x+180°) = -SIN(x°) and COS(x+180°) = -COS(x°)
    if fNEG then fNEG := FALSE;   -- toggle fNEG
            else fNEG := TRUE;
  end;
                                  -- [0 180[
  if x >= 90                      -- SIN(x+90°) = COS(x) and COS(x+90°) = -SIN(x)
  then do
    x := x - 90;
    if fSIN
    then fSIN := FALSE;
    else do
      fSIN := TRUE;
      if fNEG then fNEG = FALSE;  -- toggle fNEG
              else fNEG = TRUE;
    end;
  end;
                                  -- [0 90[
  if x = 45 then x := SQRT(0.5);
  else do

    if x > 45                     -- SIN(90°-x) = COS(x) and vice versa
    then do
      x := 90 - x;                -- [0 45[
      if fSIN then fSIN := FALSE;
              else fSIN := TRUE;
    end;

    if fSIN then x := SINDEG(x);
            else x := COSDEG(x);
  end;

  if fNEG then x := -x;

  return x;

end;


For TAN:

real function TANDEG(real x)

  boolean fNEG := FALSE;

  if x<0
  then do
    x := -x;
    fNEG := TRUE;
  end;

  x := MOD(x,180);          -- [0 180[

  if x > 90                 -- TAN(x+90°) = -TAN(90°-x)
  then do
    x := 180 - x;
    fNEG := toggle(fNEG);
  end;

  if x > 80                 -- to improve accuracy for x close to 90°
  then do
    x := 90 - x;
    x := x*PI/180;
    x := TANRAD(x);
    x := 1/x;
  end;
  else do;
    x := x*PI/180;
    x := TANRAD(x);
  end;

  if fNEG then x := -x;

  return x;

end;


Cheers, Werner

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: New firmware for the Swissmicros DM15L - Werner - 10-10-2024 06:18 AM



User(s) browsing this thread: 13 Guest(s)