Home
Scripts
Games
Referenz
     Basics:
   · Variablen
   · Datentypen
   · Operatoren
   · Funktionen
   · Pragmas
   · if else
   · while
   · for
     Libraries:
   · Lang
   · Float
   · String
   · URL
   · WMLBrowser
   · Dialogs
   · Crypto
   · WTAPublic
     Extras:
   · Arrays
   · Sortieren
   · Mathematik
Links
Gäste
Kontakt

< Mathematik >


Die WMLScript-Standard-Referenz bietet nur wenige mathematische Funktionen. Viele Mathe-Funktionen lassen sich jedoch aus dem zur Verfügung stehenden Material zusammenbasteln.

WAP-Standard, wenn nicht anderes angegeben: 1.1+


Fakultät
Formel: n! = n * (n-1) * (n-2) * ... * 1

function fac(n) {
  if(n==0) return 1;
  else if(n<0 || n!=Float.round(n)) return invalid;
  var i;
  n/=1;
  for(i=n-1;i>1;i--) n *= i;
  return n;
}

Die Nutzung der for-Schleife würde für Ganzzahlen schon bei 12! enden, da bereits 13! größer als 2147483647, der größten in WMLScript verwendbaren Ganzzahl ist.
Mit n/=1 wird eine Pseudo-Fließkommazahl geschaffen (z.B. 17/1 => 17.0).
Nun kann maximal die Fakultät von 34 berechnet werden. Das Ergebnis ist allerdings für Werte größer 4280000000.0 (?) nicht mehr hundertprozentig genau, für die nachfolgenden Formeln ist es aber dennoch hilfreich.
(Doch zeigt z.B. das Openwave SDK 5.0.0.146 ab 13! nur noch sehr ungenaue Ergebnisse und ab 19! nur noch 0.00 an, was für die weitere Verwendung in anderen Funktionen aber keine besonderen Probleme bereitet.)


Sinus
Formel: Taylor-Entwicklung von sin(x)
sin(x) = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - x^11/11! + - ...

function sin(x) {
  if(x==0) return 0;
  var vz=x/Lang.abs(x), sin_x=0, k;
  x = Float.round(Lang.abs(x)*100000000)%628318531/100000000;

  for(k=0;k<17;k++)
    sin_x += Float.pow(-1,k)*Float.pow(x,2*k+1)/fac(2*k+1);

  return String.format("%.4f",sin_x*vz);
}

Der Rückgabewert ist auf mindestens 4 Nachkommastellen genau.

Weil das Ergebnis um so präziser ist, je kleiner das Argument x ist, werden die Vielfachen von 2*Pi aus x herausgenommen.
Die Multiplikation und Division mit 10e8 ist notwendig, da der Modulo-Operator % nur mit Ganzzahlen arbeitet, aber x auch eine Fließkommazahl sein kann.
fac() ist obige Fakultäts-Funktion. (Hier bis 33!)

Zum Teil gab es Browser-Probleme mit negativen Fließkomma-Basiszahlen in der Float.pow-Funktion (z.B. in Openwave SDK 5.0.0.146). Sicherheitshalber wird deshalb in der for-Schleife der Sinus-Funktion nur mit absolutem x gearbeitet und das Ergebnis mit vz (1 oder -1) mulipliziert.


Arcus Sinus
Formel: Taylor-Entwicklung von arcsin(x)
arcsin(x) = x +1/2*x^3/3 +(1*3)/(2*4)*x^5/5 +(1*3*5)/(2*4*6)*x^7/7 +...

function arcsin(x) {
  if(Lang.abs(x)>1) return invalid;

  var vz=x/Lang.abs(x), k;
  x = Lang.abs(x);
  var arcsin_x=x;

  for(k=1;k<29;k++)
    arcsin_x += mul(2*k-1)/mul(2*k) * Float.pow(x,2*k+1)/(2*k+1);
  return String.format("%.3f",arcsin_x*vz);
}

function mul(n) {
  var i;
  n=n/1;
  for(i=n-2;i>1;i-=2) n *= i;
  return n;
}

Die Genauigkeit des Ergebnisses wird um so schlechter, je näher das Argument an 1 bzw. -1 heranreicht.
Genauigkeit bei 0.5 bzw. -0.5: 7 Nachkommastellen.
Genauigkeit bei 0.9 bzw. -0.9: 4 Nachkommastellen.
Genauigkeit bei 0.99 bzw. -0.99: nur noch eine Nachkommastelle.


Weitere trigonometrische Funktionen lassen sich durch Umformungen, oder mittels der üblichen Trigonometrie-Relationen zwischen Sinus, Cosinus und Tangens, relativ leicht aus diesen beiden Beispielen ableiten.


Natürlicher Logarithmus
Formel: Taylor-Entwicklung von ln(x)
ln(x) = (x-1) - (x-1)^2/2 + (x-1)^3/3 - (x-1)^4/4 -+ ...

function ln(x) {
  if(x<=0||x>2) return invalid;
  var k, ln_x=x-1;
  if(x<1)
    for(k=2;k<500;k++) ln_x -= Float.pow(1-x,k)/k;
  else for(k=2;k<500;k++)
    ln_x += Float.pow(-1,k+1)*Float.pow(x-1,k)/k;
  return String.format("%.2f",ln_x);
}

Berechnet werden nur Logarithmen von x mit 0 < x <= 2. Auch hier nimmt die Genauigkeit des Ergebnisses ab, je näher das Argument an 0 bzw. 2 heranreicht. Zwischen 0.01 und 2 liegt sie noch von zwei bis fünf Nachkommastellen. Unter 0.01 nimmt die Genauigkeit stark ab, wenn es bei k<500 bleibt.
Die Fallunterscheidung zwischen x<1 und x>=1 soll Probleme mit der Potenzierung negativer Fließkommazahlen abfangen. (vgl. Anm. zur Sinus-Funktion)


Binomialverteilung
Formel: (n über k) = n! / [k!*(n-k)!]

// Anzahl der verschiedenen Möglichkeiten,
// 6 Kugeln auf 49 Schalen zu verteilen.

function bin(n,k) {
  var x = n, y = k, i, b = n/k;
  for(i=1;i<y;i++) b = b * (x-i)/(y-i);
  return Float.round(b);
}

// bin(49,6) == 13983816

Da die Verwendung der Fakultäts-Funktion hier nicht viel bringt, wird die Formel gekürzt und das Ergebnis, das nun eine Fließkommazahl ist, wieder zu einer Ganzzahl gerundet.


Hexadezimalzahlen
Umwandlung einer Dezimalzahl in einen "hexadezimalen String".

function toHex(n) {
  var p=1, hex="";

  while(p<=Lang.maxInt() div 16) p *= 16;
  while(n div p == 0) p div= 16;
  while(p>0) {
    hex += String.charAt("0123456789ABCDEF",n div p);
    n %= p;
    p div= 16;
  }

  return hex;
}

Die erste while-Schleife ermittelt die größte Potenz von 16 innerhalb des erlaubten Ganzzahlenbereichs (hier 16^7 = 268435456.).
Die zweite while-Schleife verhindert Nullen vor dem Ergebnis (Es handelt sich ja um einen String).
Die dritte while-Schleife schließlich, teilt die umzuwandelnde Zahl n durch alle Potenzen von 16 und fügt für das jeweilige Ergebnis (0 bis 15) eine Ziffer zwischen 0 und F an hex an.

Analog funktioniert die Umwandlung in binäre und oktale Zahlen(-Strings) mit 2 bzw. 8 statt 16.




Copyright © 2002-2003 by wmlscript.de - Alle Rechte vorbehalten
Impressum | Datenschutz | eMail