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.
function add_float_hours_minutes(a, b)
{
var trial_sum = a+b;
// did an actual overflow occur, has the integer part incremented?
if ( Math.floor(trial_sum) > Math.floor(a)+Math.floor(b) ) {
trial_sum += 0.4;
}
// has the fractional part exceeded its allotted 60 minutes?
if ( trial_sum-Math.floor(trial_sum) >= 0.6) {
trial_sum += 0.4;
}
return trial_sum;
}
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);
sum = add_float_hours_minutes(sum, parseFloat(item));
});
que produz a seguinte saída, correta dentro de um arredondamento para o que o OP solicitou
0
0.15
0.35
4.2
5.000000000000001
7.000000000000001
7.300000000000001
12.5
13.5
15.3
16.400000000000002
19.2
20.2
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.