Wie summiere ich Float-Zahlen im Format Stunden und Minuten?
Jene. Wenn Sie zwei solcher Zahlen berechnen 0.35+3.45
, sollte dies = sein 4.20
, nicht3.80
var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]
var sum = 0.0;
arr.forEach(function(item) {
console.log(sum);
sum += parseFloat(item);
});
Das Ergebnis sollte folgendermaßen aussehen:
0
0.15
0.35
4.20
5.0
7.0
7.30
12.50
13.50
15.30
16.40
19.20
20.20
javascript
user12916796
quelle
quelle
"."
teilen Sie diese Zeichenfolgen in der Funktion nicht":"
.0.5
Stunden sollten 30 Minuten sein, alles andere ist völlig irrational. Ich hoffe, es ist nichts für einen Kunden im wirklichen Leben. Entweder arbeiten Sie mit Float-Werten einer festen Zeiteinheit oder Sie trennen Stunden / Minuten. So einfach ist das.Antworten:
Der beste Weg, mit solchen "verrückten" Datenformaten umzugehen, besteht darin, sie zuerst in ein vernünftiges und leicht verarbeitbares Format zu konvertieren, mit den konvertierten Daten alles zu tun, was Sie tun müssen, und schließlich (wenn Sie es unbedingt müssen) die Ergebnisse wieder in zu konvertieren das ursprüngliche Format.
(Natürlich besteht die wirkliche Lösung darin, die Verwendung solcher verrückten Zeitdarstellungen gänzlich einzustellen. Dies ist jedoch nicht immer praktisch, z. B. weil Sie eine Schnittstelle zu einem Legacy-System herstellen müssen, das Sie nicht ändern können.)
In Ihrem Fall wäre ein geeignetes vernünftiges Format für Ihre Daten beispielsweise eine ganzzahlige Anzahl von Minuten. Sobald Sie Ihre Daten in dieses Format konvertiert haben, können Sie gewöhnliche Arithmetik ausführen.
Beachten Sie, dass der obige Konvertierungscode zuerst den Eingabe-Float mit 100 multipliziert und auf eine Ganzzahl rundet, bevor die Stunden- und Minutenteile getrennt werden. Dies sollte Eingaben mit möglichen Rundungsfehlern robust behandeln und gleichzeitig die Notwendigkeit vermeiden, die Eingaben zu stringifizieren.
Der Grund für besondere Vorsicht ist, dass die Zahl 0,01 = 1/100 (und die meisten ihrer Vielfachen) im von JavaScript verwendeten binären Gleitkommaformat nicht genau darstellbar ist . Daher können Sie keine JS-Nummer haben, die genau 0,01 entspricht. Das Beste, was Sie haben können, ist eine Nummer, die so nahe beieinander liegt, dass beim Konvertieren in eine Zeichenfolge der Fehler automatisch ausgeblendet wird. Der Rundungsfehler ist jedoch weiterhin vorhanden und kann Sie beißen, wenn Sie beispielsweise versuchen, solche Zahlen mit einem genauen Schwellenwert zu vergleichen. Hier ist eine schöne und einfache Demonstration:
quelle
Sie können diese Logik verwenden, nachdem Sie eine einfache arithmetische Addition durchgeführt haben. Dadurch wird die Summe in das Zeitformat konvertiert
quelle
math.floor(sample/1)
statt nurmath.floor(sample)
?sample / 1
, ich denke, JS wird es selbst auf den Boden legen, weil es keine Dezimalstelle im Divisor gab (wie insample / 1.0
, seit ziemlich langer Zeit JS verwendet;), aber es hat nicht so schnell gegoogelt und hinzugefügtfloor
habe vergessen, das zu entfernen. Trotzdem danke, dassarr
nicht im Ergebnis enthalten ist. Zum Beispiel, wennarr = [1.5, 2.5]
das Ergebnis4
anstelle von4.4
Los geht's, Implementierung in Javascript ES6. Ich habe jedes Element durchgeschleift und Stunden, Minuten nach geteilt
.
, überprüft, ob Minuten nicht vorhanden sind, andernfalls 0 zugewiesen, die Gesamtzahl der Stunden und Minuten gezählt und die erforderliche Berechnung angewendet.quelle
Sie müssen alles entweder in Stunden oder in Minuten umrechnen und dann rechnen.
quelle
Sie müssen sie zuerst in Stunden und Minuten konvertieren
quelle
Darf ich wissen, warum das erste Ergebnis 0 sein soll ? Unten finden Sie eine Möglichkeit, dies mit einer einzelnen Schleife zu tun. Kommentare sind im Code zu erklären. Mit jeder Schleife addieren wir die Minuten. Wenn sie größer als 60 sind, addieren wir eine Stunde und verwenden dann % 60 , um die verbleibenden Minuten zu erhalten. Schwimmer können ein Schmerz sein, mit dem man arbeiten muss,
Also habe ich die Zahlen in eine Zeichenfolge konvertiert und dann zurück in eine int.
quelle
toString().split('.');
- Argh, wirklich?quelle
0.15 + 0.2
Warum=0.17
? Muss sein0.35
Die Standardmethode zum Reduzieren eines Moduls besteht darin, das Defizit nach dem Hinzufügen zu addieren, wenn ein Überlauf verursacht wurde. So würden Sie die BCD-Addition beispielsweise mit binärer Hardware durchführen.
Obwohl Sie können zusätzlich mit Schwimmern auf diese Weise zu tun, gibt es eine Frage, ob man sollte . Die Probleme bei der Verwendung von Gleitkommazahlen für Operationen mit im Wesentlichen ganzzahligen Mengen sind bekannt, und ich werde sie hier nicht erneut aufbereiten.
Normalerweise arbeitet die Addition von Float-Brüchen implizit mit einem Modul von 1,0, ein Überlauf aus dem Bruch erhöht den ganzzahligen Teil. Wenn wir den Punkt als Stunden.Minuten-Trennzeichen interpretieren, möchten wir, dass der Bruch bei 0,6 überläuft. Dazu muss das Defizit von 0,4 zum richtigen Zeitpunkt addiert werden.
Dies erzeugt die folgende Ausgabe, die innerhalb einer Rundung auf das korrigiert wird, was das OP verlangt hat
Ich habe die endgültige Formatierung als Übung für den Leser auf zwei Dezimalstellen belassen. Die 15 nachgestellten Ziffern in all ihrer Pracht veranschaulichen einen Teil dessen, warum die Verwendung von Floats nicht der beste Weg ist, dies zu tun.
Überlegen Sie auch, was passiert, wenn Sie Sekunden oder Tage einschließen möchten. Die beiden eher üblichen Methoden, entweder Sekunden oder ein Tupel von ganzen Zahlen zu schweben, sehen plötzlich viel sinnvoller aus.
quelle