Christoph Zurnieden: genau Rechnen in JS

Beitrag lesen

Hi,

Ok, habe mit eurer Hilfe diese schöne Fkt. gefunden, die mich jetzt gerettet hat:

function dezRound(num,pos)

Ja, eine nette Rundungsfunktion. Warum aber möchtest Du nicht das Problem selber angehen und bevorzugst einen mühseligen "Würg-around"?
Was ist mit toFixed() und  toPrecision() aus Selfhtml?
Erst in Javascript 1.5? Gut, kann ein Argument sein, gebe ich zu.

if(y == 1.6) return;
Das wird ja dann leider nichts.

Nein, das wird nix. Das liegt daran, das Du im Dezimalsystem notierst und der Computer aber nur Binär versteht und umrechnen muß. zweimal in Deinem Fall. Das kann schonmal zu Verlusten führen.
Dieser Fehler ist jedoch genau definierbar und heißt meist Epsilon "ε". Normalerweise wird der auch irgendwo als Wert zur Verfügung gestellt, ist in Javascript jedoch nicht zu finden. Warum auch immer. Da ε architekturabhängig ist läßt er sich also nur rechnerisch ermitteln. Eine, wenn auch recht brutale Methode ist:

var tmp1    = 1.0;
var tmp2    = 0.0;
var EPSILON = 0.0;
do{
  mchEps = tmp1;
  tmp1  /= 2;
  tmp2   = 1.0 + tmp1;
}while (tmp2 > 1.0);

"tmp1" wird so lange halbiert (ist ja ein Binärsystem!) bis es so klein ist, das 1.0 plus des Wertes aus tmp1 nicht mehr größer als 1.0 ist. Das heißt übrigens nicht, das beide exakt gleich sind! Die Rechnung oben geht übrigens auch in Javascript recht flott und kann bei Bedarf entsprechend eingesetzt werden, onload böte sich da an.

Mit dem so gewonnenem Wert kann nun verglichen werden.

Statt

if(wert1 == wert2)

wäre dieses passender

if(Math.abs(wert1 - wert2) < Math.abs(wert1 * EPSILON)){
  alert(wert1 + " und " + wert2 + " sind ziemlich gleich");
}
else{
  alert(wert1 + " und " + wert2 + " sind nicht gleich");
}

Aus Deinem

if(y == 1.6) return;

würde also

if(Math.abs(x - 1.6) < Math.abs(x * EPSILON)) return;

und ausreichend funktionieren.

Ja, das _ist_ kompliziert, zumindest auf den ersten Blick.
Aber diese Schwierigkeiten bestehen seitdem das Binärsystem auf Computern angewandt wird und ist somit ein sehr gut bekanntes Feld.

Da das aber auch viel Schreiberei ist und daher fehleranfällig, würde ich vorschlagen, da eine eigene Funktion draus zu machen.

so short

Christoph Zurnieden