Möglichkeiten des S7-C-Compilers

Barnee

Level-1
Beiträge
71
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich stelle nachfolgend mal eine Funktion vor, von der ich der Meinung bin, dass man eine solche Konstruktion nicht ohne Schwierigkeiten in AWL umsetzen kann. Hierbei handelt es sich um ein Iterationsverfahren nach Newton und diese ist in der hier vorgestellten Art der Ausführung als universell anwendbare C-Funktion in andere herkömmliche C-Projekte einsetzbar. Die notwendigen Funktionen zur Aproximation werden als Funktionspointer - (*nf) - mit der notwendigen Parametern übergeben.

Code:
extd newton (extd start, extd step, extd (*nf)(extd, void *), extd convg,
              extd *max, extd *min, long maxLoops, void *pb, long *msg, long ID)
{
   extd     x0, x1, y1, x2, y2, maxi, mini;
   long     n;
   str255   s;

   inc_fn_stack ("newton");
   maxi = (max != NULL) ? *max : 0.0;
   mini = (min != NULL) ? *min : 0.0;

   if (DebugNewton)
   {
      strcpy  (s, "Newton Start: ");
      strcat  (s, newtonID (ID));
      sprintf (s,
         "\tx1: %6.2f\tdx: %6.2f\te: %6.2f\thi: %6.2f\tlo: %6.2f\tn<%ld\n",
          (float) start, (float) step, (float) convg, (float) maxi,
          (float) mini, maxLoops);
      printf (s);
   }

   x1 = start;
   x2 = start + step;
   y2 = (*nf) (x1, pb);

   if (DebugNewton)
   {
      strcpy  (s, "Newton: f(1): ");
      strcat  (s,  newtonID (ID));
      sprintf (s, " y2 = f(x1): x1 = %6.2f y2 = %6.2f\n",
              (float) x1, (float) y2);
      printf  (s);
   }

   for (n = 0; n < maxLoops; n++)
   {
      y1 = y2;
      y2 = (*nf) (x2, pb);  /* returns the difference by function call */

      if (DebugNewton)
      {
         strcpy  (s, "Newton: f(2): ");
         strcat  (s, newtonID (ID));
         sprintf (s, " y2 = f(x2): x1 = %6.2f y2 = %6.2f\n",
                 (float) x2, (float) y2);
         printf  (s);
      }

      if (fABS(y2) < convg)
      {
         if (min != NULL)
            if (x2 < *min)
            {
               *msg = msgLo;
               dec_fn_stack ();
               return *min;
            }

         if (max != NULL)
            if (x2 > *max)
            {
               *msg = msgHi;
               dec_fn_stack ();
               return *max;
            }

         *msg = noErr;
         dec_fn_stack ();
         return x2;
      }

      if (fABS(y2 - y1) < d_ZDP)
      {
         *msg = msgZDP;
         dec_fn_stack ();
         return x2;
      }

      x0 = x1 - y1 * (x2 - x1) / (y2 - y1);

      if (min != NULL)
         x0 = fMAX (x0, *min);
      if (max != NULL)
         x0 = fMIN (x0, *max);

      x1 = x2;
      x2 = x0;
   }

   *msg = msgMaxLoop;

   dec_fn_stack ();
   return 0;
}

Ich stelle dies mal als Start zur Diskussion in das Forum und würde gerne eure Meinung über die Machbarkeit hören.

Gruß Barnee
 
Zurück
Oben