Como somar números flutuantes no formato de horas e minutos?
Essa. se calcular dois desses números 0.35+3.45
, deve ser = 4.20
, não3.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);
});
O resultado deve ser assim:
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
fonte
fonte
"."
para dividir essas strings, não":"
.0.5
horas devem ser de 30 minutos, qualquer outra coisa é completamente irracional. Espero que não seja para um cliente na vida real. Trabalhe com valores flutuantes de uma unidade de tempo fixa ou separe horas / minutos. Tão simples como isso.Respostas:
A melhor maneira de lidar com formatos de dados "malucos" como esse é primeiro convertê-los em um formato sadio e facilmente processável, fazer o que for necessário usando os dados convertidos e finalmente (se for necessário) converter os resultados novamente para o formato original.
(Obviamente, a solução real é parar de usar essas representações de tempo totalmente loucas. Mas isso nem sempre é prático, por exemplo, porque você precisa interagir com um sistema legado que não pode mudar.)
No seu caso, um formato adequado para os seus dados seria, por exemplo, um número integral de minutos. Depois de converter seus dados para esse formato, você poderá fazer aritmética comum.
Observe que o código de conversão acima primeiro multiplica o valor flutuante da entrada por 100 e o arredonda para um número inteiro antes de separar as partes da hora e do minuto. Isso deve manipular de maneira robusta as entradas com possíveis erros de arredondamento, evitando a necessidade de especificar as entradas.
O motivo para ter cuidado extra aqui é porque o número 0,01 = 1/100 (e a maioria de seus múltiplos) não é exatamente representável no formato de ponto flutuante binário usado pelo JavaScript. Portanto, você não pode realmente ter um número JS que seria exatamente igual a 0,01 - o melhor que você pode ter é um número tão próximo que a conversão em uma string ocultará automaticamente o erro. Mas o erro de arredondamento ainda existe, e você pode mordê-lo se você tentar fazer coisas como comparar esses números com um limite exato. Aqui está uma demonstração agradável e simples:
fonte
Você pode usar essa lógica depois de fazer uma adição aritmética simples, isso converterá a soma em formato de hora
fonte
math.floor(sample/1)
invés de apenasmath.floor(sample)
?sample / 1
, embora o JS seja o próprio piso porque não havia decimal no divisor (como emsample / 1.0
, há muito tempo desde que o JS foi usado;), mas não funcionou, então procurei rapidamente no Google e adicioneifloor
, esqueci de remover isso. De qualquer forma obrigado por apontar quearr
não estão no resultado. Por exemplo, searr = [1.5, 2.5]
o resultado será em4
vez de4.4
Aqui está, implementação em Javascript ES6. Passei um loop em cada elemento e divido horas, minutos por
.
, verifiquei se minutos não existem, ou seja, atribua 0 a contar o total de horas e minutos e apliquei a computação necessária.fonte
Você precisa converter tudo em horas ou minutos e depois fazer as contas.
fonte
Você precisa convertê-los para horas e minutos primeiro
fonte
Posso saber por que você deseja que o primeiro resultado seja 0 ? Abaixo está uma maneira de fazer isso com um único loop. Os comentários estão no código para explicar. A cada loop, adicionamos os minutos e, se forem maiores que 60, adicionamos uma hora e usamos % 60 para obter os minutos restantes. Flutuar pode ser uma dor de se trabalhar,
Então, converti os números em uma string e depois voltei a um int.
fonte
toString().split('.');
- argh, sério?fonte
0.15 + 0.2
Por quê=0.17
? Deve ser0.35
A maneira padrão de reduzir um módulo é adicionar o déficit após o acréscimo se um estouro foi causado. É assim que você faria a adição do BCD usando hardware binário, por exemplo.
Embora você possa fazer acréscimos usando carros alegóricos dessa maneira, há uma questão de saber se você deveria . Os problemas com o uso de números flutuantes para operar em quantidades basicamente inteiras são bem conhecidos, e não vou reformulá-los aqui.
Normalmente, a adição em frações flutuantes funciona implicitamente com um módulo de 1,0, um excesso da fração incrementa a parte inteira. Se interpretarmos o ponto como o separador hours.minutes, queremos que a fração transborde em 0,6. Isso precisa que o déficit de 0,4 seja adicionado no momento apropriado.
que produz a seguinte saída, correta dentro de um arredondamento para o que o OP solicitou
Deixei a formatação final com duas casas decimais como exercício para o leitor. Os 15 dígitos à direita em toda a sua glória ilustram parte do motivo pelo qual usar carros alegóricos não é a melhor maneira de fazer isso.
Além disso, considere o que acontece quando você deseja incluir segundos ou dias. As duas maneiras mais comuns de segundos flutuantes ou uma tupla de números inteiros parecem subitamente muito mais sensatas.
fonte