Comment additionner des nombres flottants au format heures et minutes?
Ceux. si calculer deux de ces nombres, 0.35+3.45
alors il devrait être = 4.20
, pas3.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);
});
Le résultat devrait être comme ceci:
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
la source
la source
"."
pour diviser ces chaînes, non":"
.0.5
les heures devraient être de 30 minutes, tout le reste est complètement irrationnel. J'espère que ce n'est pas pour un client dans la vraie vie. Soit vous travaillez avec des valeurs flottantes d'une unité de temps fixe, soit vous séparez les heures / minutes. Aussi simple que cela.Réponses:
La meilleure façon de gérer des formats de données «fous» comme celui-ci est de les convertir d'abord en un format sain et facilement traitable, de faire tout ce que vous devez faire en utilisant les données converties et enfin (si vous devez absolument) de reconvertir les résultats en le format d'origine.
(Bien sûr, le vrai solution est d'arrêter complètement d'utiliser des représentations de temps aussi folles. Mais ce n'est pas toujours pratique, par exemple parce que vous devez vous interfacer avec un système hérité que vous ne pouvez pas changer.)
Dans votre cas, un format sain pour vos données serait par exemple un nombre entier de minutes. Une fois que vous avez converti vos données dans ce format, vous pouvez ensuite faire de l'arithmétique ordinaire dessus.
Notez que le code de conversion ci-dessus multiplie d'abord le flottant d'entrée par 100 et l'arrondit à un entier avant de séparer les parties heure et minute. Cela devrait gérer de manière robuste les entrées avec d'éventuelles erreurs d'arrondi tout en évitant d'avoir à filtrer les entrées.
La raison de prendre des précautions supplémentaires ici est que le nombre 0,01 = 1/100 (et la plupart de ses multiples) n'est pas réellement représentable exactement au format binaire à virgule flottante utilisé par JavaScript. Ainsi, vous ne pouvez pas réellement avoir un nombre JS qui serait exactement égal à 0,01 - le mieux que vous puissiez avoir est un nombre si proche que sa conversion en chaîne masquera automatiquement l'erreur. Mais l'erreur d'arrondi est toujours là et peut vous mordre si vous essayez de faire des choses comme comparer de tels nombres à un seuil exact. Voici une démonstration agréable et simple:
la source
Vous pouvez utiliser cette logique après avoir fait un simple ajout arithmétique, cela convertira la somme au format d'heure
la source
math.floor(sample/1)
au lieu de justemath.floor(sample)
?sample / 1
, je pensais que JS l'établirait lui-même car il n'y avait pas de décimale dans le diviseur (comme danssample / 1.0
JS depuis longtemps;), mais il ne l'a pas fait, j'ai donc rapidement googlé et ajoutéfloor
, j'ai oublié de supprimer cela. Quoi qu'il en soit, merci d'avoir souligné quearr
non sur le résultat. Par exemple, siarr = [1.5, 2.5]
le résultat sera4
au lieu de4.4
Voilà, implémentation en Javascript ES6. J'ai bouclé chaque élément et divisé les heures, les minutes par
.
, vérifié si les minutes sont inexistantes sinon attribuez 0 compte le total des heures et des minutes et appliqué le calcul nécessaire.la source
Vous devez tout convertir en heures ou en minutes, puis faire le calcul.
la source
Vous devez d'abord les convertir en heures et minutes
la source
Puis-je savoir pourquoi vous voulez que le premier résultat soit 0 ? Ci-dessous est un moyen de le faire avec une seule boucle. Les commentaires sont dans le code pour expliquer. Avec chaque boucle, nous ajoutons les minutes, et si elles sont supérieures à 60, nous ajoutons une heure, puis utilisons % 60 pour obtenir les minutes restantes. Les flotteurs peuvent être pénibles à travailler,
J'ai donc converti les nombres en chaîne, puis de nouveau en entier.
la source
toString().split('.');
- argh, vraiment?la source
0.15 + 0.2
Pourquoi=0.17
? Doit être0.35
La manière standard de réduire un module est d'ajouter le déficit après l'ajout en cas de débordement. C'est ainsi que vous feriez l'ajout de BCD en utilisant du matériel binaire par exemple.
Bien que vous puissiez faire des ajouts en utilisant des flottants de cette manière, il y a une question de savoir si vous devriez . Les problèmes liés à l'utilisation de nombres flottants pour opérer sur des quantités fondamentalement entières sont bien connus, et je ne vais pas les ressasser ici.
Normalement, l'addition sur les fractions flottantes fonctionne implicitement avec un module de 1,0, un débordement hors de la fraction incrémente la partie entière. Si nous interprétons le point comme le séparateur heures.minutes, nous voulons que la fraction déborde à 0,6. Il faut pour cela ajouter le déficit de 0,4 au moment opportun.
qui produit la sortie suivante, correcte à l'intérieur d'un arrondi à ce que le PO a demandé
J'ai laissé le formatage final à deux décimales comme exercice pour le lecteur. Les 15 chiffres de fin dans toute leur splendeur illustrent en partie pourquoi l'utilisation de flotteurs n'est pas la meilleure façon de le faire.
Réfléchissez également à ce qui se passe lorsque vous souhaitez inclure des secondes ou des jours. Les deux méthodes plutôt standard de flottement des secondes, ou d'un tuple d'entiers, semblent tout à coup beaucoup plus sensées.
la source