Jak sumować liczby zmiennoprzecinkowe w formacie godzin i minut?
Te. jeśli obliczymy dwie takie liczby, 0.35+3.45
to powinno być = 4.20
, nie3.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);
});
Wynik powinien wyglądać następująco:
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
użytkownik12916796
źródło
źródło
"."
aby podzielić te ciągi, a nie":"
.0.5
godziny powinny wynosić 30 minut, wszystko inne jest całkowicie irracjonalne. Mam nadzieję, że nie jest to dla klienta w rzeczywistości. Albo pracuj z wartościami zmiennoprzecinkowymi ustalonej jednostki czasu, albo oddzielaj godziny / minuty. Tak proste jak to.Odpowiedzi:
Najlepszym sposobem radzenia sobie z takimi „szalonymi” formatami danych jest najpierw przekonwertowanie ich na rozsądny i łatwy do przetworzenia format, zrób wszystko, co musisz zrobić, używając przekonwertowanych danych, a na koniec (jeśli absolutnie musisz) przekonwertować wyniki z powrotem na oryginalny format.
(Oczywiście, prawdziwym rozwiązaniem jest całkowite zaprzestanie używania tak zwariowanych reprezentacji czasu. Ale to nie zawsze jest praktyczne, np. Ponieważ musisz połączyć się ze starszym systemem, którego nie możesz zmienić).
W twoim przypadku odpowiednim rozsądnym formatem twoich danych będzie np. Całkowita liczba minut. Po przekonwertowaniu danych na ten format możesz wykonywać na nim zwykłą arytmetykę.
Zauważ, że powyższy kod konwersji zwielokrotnia liczbę zmiennoprzecinkową przez 100 i zaokrągla ją do liczby całkowitej przed oddzieleniem części godziny i minut. Powinno to skutecznie obsłużyć dane wejściowe z możliwymi błędami zaokrąglania, unikając przy tym konieczności ich usztywnienia.
Powodem, dla którego należy zachować szczególną ostrożność, jest to, że liczba 0,01 = 1/100 (i większość jej wielokrotności) nie jest właściwie dokładnie reprezentowana w binarnym formacie zmiennoprzecinkowym używanym przez JavaScript. Tak więc nie możesz faktycznie mieć liczby JS, która byłaby dokładnie równa 0,01 - najlepszą, jaką możesz mieć, jest liczba tak bliska, że konwersja jej na ciąg automatycznie ukryje błąd. Ale błąd zaokrąglania nadal występuje i może cię ugryźć, jeśli spróbujesz zrobić takie rzeczy, jak porównanie takich liczb z dokładnym progiem. Oto ładna i prosta demonstracja:
źródło
Możesz użyć tej logiki po prostym dodaniu arytmetycznym, co spowoduje konwersję sumy do formatu czasu
źródło
math.floor(sample/1)
zamiast tylkomath.floor(sample)
?sample / 1
, myślałem, że JS sam to zrobi, ponieważ w dzielniku nie było miejsc po przecinku (jak zasample / 1.0
dość długi czas, odkąd użyłem JS;), ale tak się nie stało, więc szybko googlowałem i dodałemfloor
, zapomniałem to usunąć. W każdym razie dzięki za wskazanie tegoarr
nie ma w wyniku. Na przykład, jeśliarr = [1.5, 2.5]
wynikiem będzie4
zamiast4.4
Proszę bardzo, wdrożenie w Javascript ES6. Zapętliłem każdy element i dzieliłem godziny, minuty
.
, sprawdziłem, czy minuty nie istnieją, przypisz 0 policz sumę godzin i minut i zastosowałem niezbędne obliczenia.źródło
Musisz przeliczyć wszystko na godziny lub minuty, a następnie wykonać obliczenia matematyczne.
źródło
Najpierw musisz przeliczyć je na godziny i minuty
źródło
Czy mogę wiedzieć, dlaczego chcesz, aby pierwszy wynik wynosił 0 ? Poniżej znajduje się sposób na zrobienie tego za pomocą pojedynczej pętli. Komentarze są w kodzie do wyjaśnienia. Z każdą pętlą dodajemy minuty, a jeśli są one większe niż 60, dodajemy godzinę, a następnie używamy % 60, aby uzyskać pozostałe minuty. Pływaki mogą być uciążliwe w pracy,
Przekształciłem więc liczby na ciąg znaków, a następnie z powrotem na liczbę całkowitą.
źródło
toString().split('.');
- argh, naprawdę?źródło
0.15 + 0.2
Dlaczego=0.17
? Musi być0.35
Standardowym sposobem zmniejszenia modułu jest dodanie deficytu po dodaniu, jeśli nastąpiło przepełnienie. W ten sposób można dodawać BCD na przykład przy użyciu sprzętu binarnego.
Mimo, że można zrobić za pomocą pływaków dodatek w ten sposób, nie jest kwestia tego, czy powinien . Problemy z używaniem liczb zmiennoprzecinkowych do operowania na liczbach całkowitych są dobrze znane i nie zamierzam ich tutaj przerabiać.
Zwykle dodawanie ułamków swobodnych działa domyślnie z modułem 1,0, przelew z ułamka zwiększa część całkowitą. Jeśli interpretujemy punkt jako separator godzin. Minut, chcemy, aby ułamek przepełniał się przy 0,6. W tym celu należy dodać deficyt w wysokości 0,4.
co daje następujący wynik, popraw w zaokrągleniu do tego, o co poprosił PO
Ostateczne formatowanie zostawiłem do dwóch miejsc po przecinku jako ćwiczenie dla czytelnika. 15 końcowych cyfr w całej okazałości ilustruje, dlaczego używanie pływaków nie jest najlepszym sposobem na zrobienie tego.
Zastanów się także, co się stanie, jeśli chcesz uwzględnić sekundy lub dni. Dwa raczej bardziej standardowe sposoby albo sekund zmiennoprzecinkowych, albo krotkę liczb całkowitych, nagle wyglądają na znacznie rozsądniejsze.
źródło