Wert einer Variable in Schritte einteilen

Wessy

Erfahrenes Mitglied
Hallo liebe 'Kollegen',

habe ein Problem welches ich auch nach Google-Suche und Suche hier im Forum irgendwie nicht gelöst bekomme.

Und zwar habe ich einen Wert welchen ich quasi an Schritte angleichen möchte. Wie z.B. hier:
PHP:
var value=125.27;
var step=0.1;
Als Resultat möchte ich gerne "125.3" haben.

Wie kann ich das Lösen? "value" und "step" möchte ich später noch verändern können. Also wäre ein Wert von 3 und eine Schrittweite von 10 auch möglich. Das muss doch irgendwie zu lösen sein.

PS.: ist zwar eine 'allgemeine' Berechnung, aber gepostet unter "Javascript" da ich nur mit der üblichen Berechnungen sowie der Math-Bib arbeiten kann.
 
Zuletzt bearbeitet:
Hallo Hela,

vielen Dank für die Antwort. Ich muss gestehen dass ich diese Berechnung bislang auch nutze. Habe gehofft dass wenn ich es so nicht reinschreibe evtl noch eine anderer Ansatz 'ans Licht' kommt. Schande auf mein Haupt.

Denn warum ich mich hier gemeldet habe ist letzlich, dass Javascript (zumindest im FF) einfach nicht so sauber rechnet wie 'wir beide'! Ergebnis ist nämlich:
PHP:
var result=Math.round(value/step)*step;/*125.30000000000001*/
Jetzt ließe sich auf Nachkommestellen wieder runden (was Math allerdings von Haus aus nicht bietet). Das stellt mich alles nicht so zufrieden! :-(

PS.: In der Tat liegt mein letzter Mathematikunterricht recht lang zurück! :D
 
Ja - Problem jetzt erkannt:
Wenn ich mich recht erinnere konnte man das mit einer Dezimalinflation in den Griff bekommen, da es mit ganzzahligen Werten gerechnet funktionieren müsste.
Ich muss mal auf meinen Festplatten wühlen. Sicherlich findet sich etwas ...
 
Hmm, habe nochmal nach den 'Rechnungsfehlern' geschaut. Grund ist wohl dass Javascript beim Rechnen selbst in das Binärformat umwandelt (was z.B. CPU's auch tun, dies aber ohne 'Fehler').

Falls jemand anderes ebenfalls so ein Problem hat: - hier eine Beispiellösung -
PHP:
var value=125.27;
var step=0.1;
var result=Math.round(value/step)*step;

//nachfolgende 2 Zeilen nur für 'dynamische' Rundung gemäß Nachkommastellen der Variable "step"
var divmul=String(step);
if(divmul.indexOf('.')==-1){divmul='';}else{divmul=divmul.substr(divmul.indexOf('.')+1);}
//hier könnte man auch "divmul.length" durch eine feste Anzahl Nachkommastellen ersetzen
divmul=Math.pow(10,divmul.length);
var result=Math.round(result*divmul)/divmul;

EDIT: Ha, da haben sich unsere Post's überschnitten. Trotzdem danke dir. :)
 
Zuletzt bearbeitet:
So müsste es auch funktionieren:
Javascript:
var val = 125.27;
var step = 0.1;
var inflFaktor = 1, result;

while(step < 1)
{
  inflFaktor *= 10;
  val *= 10;
  step *= 10;
}

result = Math.round(val/step)*step/inflFaktor;

Korrektur:
Habe gerade mal damit rumgespielt und bemerkt, dass oben stehender Vergleich doch nicht für alle Werte geeignet ist. Besser wäre folgendes:

Javascript:
var val = 125.27;
var step = 0.1;
var inflFaktor = 1, result;

while(step != Math.floor(step))
{
  inflFaktor *= 10;
  val *= 10;
  step *= 10;
}

result = Math.round(val/step)*step/inflFaktor;
 
Zuletzt bearbeitet von einem Moderator:
Hallo Hela,
cool. Sehr guter Ansatz. 1. alle Werte so lange nach 'nach links' verschieben bis der "Step" kein Komma mehr hat (und somit keine Probleme bereitet) 2. die eigentliche Berechnung 3. die Nachkommastellen wieder 'herrichten'. :)

Es könnte sogar sein dass die Lösung von der Geschwindigkeit her schneller ist da keine FP- sondern Integer-Berechnung vorliegt. Wichtig da es um ein paar millionen dieser Berechnungen pro Sek geht. DANKE erstmal. Poste evtl später noch mal bzgl Leistung.
 
Hallo Wessy,
habe inzwischen bemerkt, dass Javascript auch bei der Multiplikation [step *= 10] u.U. "krumme" Werte berechnet. Deshalb ist deine Lösung besser, den Inflationsfaktor aus den Nachkommastellen von step zu berechnen, da dann das Produkt nur einmal gerundet werden muss. Das würde z.B. folgendermaßen aussehen:
Javascript:
var val = 355.113;
var step = 1.025;
var inflFaktor = 1;

if(String(step).indexOf(".")>-1)
	inflFaktor = Math.pow(10,String(step).split(".")[1].length);
var inflStep = Math.round(step*inflFaktor);
var result = Math.round(val/step)*inflStep/inflFaktor;
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

partielle Blindheit beseitigt: :-(
Es gibt unter Javascript ein Number-Objekt mit der Methode toFixed(). Damit wird ein numerischer Wert auf eine bestimmte Anzahl von Nachkommastellen festgelegt und auch eine kaufmännische Rundung durchgeführt. Damit wird das natürlich alles ganz einfach:
Javascript:
var val = 345.113;
var step = 13.007;
var strStep = String(step);

// Anzahl der Nachkommastellen:
var nkStellen = 0;
if(strStep.indexOf(".")>-1)
	nkStellen = strStep.split(".")[1].length;

var result = Math.round(val/step)*step;
var fResult = result.toFixed(nkStellen);
Ergebnis:
val = 345.113
step = 13.007

nkStellen = 3
result = 351.18899999999996
fixedResult = 351.189
 
Zuletzt bearbeitet von einem Moderator:
Oh geil. Dann ist das Thema gleich 2x 'erledigt'.
partielle Blindheit
Oh wie recht du hast. Habe mir seitdem ich mich mit dem Problem beschäftigt habe alle Math-Funktionen auf die Stirn geschrieben, aber Number habe ich nicht richtig durchgeschaut. Danke dir Hela!
 
Zurück