La forma estándar de reducir un módulo es agregar el déficit después de la adición si se produjo un desbordamiento. Así es como haría la adición de BCD utilizando hardware binario, por ejemplo.
Aunque puede hacer la suma usando flotadores de esta manera, hay una cuestión de si debería hacerlo . Los problemas con el uso de números flotantes para operar en lo que son básicamente cantidades enteras son bien conocidos, y no los voy a repetir aquí.
Normalmente, la suma de fracciones flotantes funciona implícitamente con un módulo de 1.0, un desbordamiento de la fracción incrementa la parte entera. Si interpretamos el punto como el separador de horas.minutos, entonces queremos que la fracción se desborde en 0.6. Esto necesita que se agregue el déficit de 0.4 en el momento apropiado.
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 produce el siguiente resultado, correcto dentro de un redondeo a lo que solicitó el OP
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
Dejé el formato final a dos decimales como ejercicio para el lector. Los 15 dígitos finales en todo su esplendor ilustran parte de por qué usar flotadores no es la mejor manera de hacerlo.
Además, considere lo que sucede cuando desea incluir segundos o días. Las dos formas bastante más estándar de segundos flotantes, o una tupla de enteros, de repente parecen mucho más sensatas.