Как суммировать числа с плавающей точкой в формате часов и минут?
Те. если вычислить два таких числа, 0.35+3.45
то должно быть = 4.20
, а не3.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);
});
Результат должен быть таким:
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
источник
источник
"."
для разделения этих строк, а не":"
.0.5
часы должны быть 30 минут, все остальное совершенно иррационально. Я надеюсь, что это не для клиента в реальной жизни. Либо работайте с плавающими значениями фиксированной единицы времени, либо вы разделяете часы / минуты. Так просто.Ответы:
Лучший способ справиться с такими «сумасшедшими» форматами данных, как это, - сначала преобразовать их в разумный и легко обрабатываемый формат, сделать все, что вам нужно, используя преобразованные данные, и, наконец, (если вам абсолютно необходимо) преобразовать результаты обратно в оригинальный формат.
(Конечно, реальное решение состоит в том, чтобы прекратить использовать такие сумасшедшие представления времени полностью. Но это не всегда практично, например, потому что вам нужно взаимодействовать с устаревшей системой, которую вы не можете изменить.)
В вашем случае подходящий нормальный формат для ваших данных будет, например, целое число минут. После того, как вы преобразовали свои данные в этот формат, вы можете сделать обычную арифметику с ним.
Обратите внимание, что приведенный выше код преобразования сначала умножает входное значение с плавающей точкой на 100 и округляет его до целого числа, а затем разделяет часовую и минутную части. Это должно надежно обрабатывать входные данные с возможными ошибками округления, избегая при этом необходимости структурировать входные данные.
Причиной особой осторожности здесь является то, что число 0,01 = 1/100 (и большинство его кратных) на самом деле не совсем точно представлено в двоичном формате с плавающей запятой, используемом JavaScript. Таким образом, вы на самом деле не можете иметь число JS, которое было бы точно равно 0,01 - лучшее, что вы можете иметь, это число, которое настолько близко, что преобразование его в строку автоматически скрывает ошибку. Но ошибка округления все еще существует, и она может вас укусить, если вы попытаетесь сделать что-то вроде сравнения таких чисел с точным порогом. Вот хорошая и простая демонстрация:
источник
Вы можете использовать эту логику после выполнения простого арифметического сложения, которое преобразует сумму в формат времени
источник
math.floor(sample/1)
вместо простоmath.floor(sample)
?sample / 1
, я, хотя JS и сам напишу об этом, потому что в делителе не было десятичной дроби (какsample / 1.0
, например, довольно давно с тех пор, как использовал JS;), но это не так, я быстро нагуглил и добавилfloor
забыл удалить это. В любом случае спасибо за указание на этоarr
не для результата. Например, еслиarr = [1.5, 2.5]
результат будет4
вместо4.4
Вот, пожалуйста, реализация в Javascript ES6. Я зациклил каждый элемент и разделил часы, минуты на
.
, проверил, не существует ли минут, иначе присвоил 0, подсчитал общее количество часов и минут и применил необходимые вычисления.источник
Вы должны преобразовать все в часы или в минуты, а затем сделать математику.
источник
Вы должны сначала преобразовать их в часы и минуты
источник
Могу ли я узнать, почему вы хотите, чтобы первый результат был 0 ? Ниже приведен способ сделать это с помощью одного цикла. Комментарии в коде, чтобы объяснить. С каждым циклом мы добавляем минуты, и если они больше 60, мы добавляем час, а затем используем % 60, чтобы получить оставшиеся минуты. Поплавки могут быть болью для работы,
Таким образом, я преобразовал числа в строку, а затем обратно в int.
источник
toString().split('.');
- правда, правда?источник
0.15 + 0.2
Почему=0.17
? Должно быть0.35
Стандартный способ уменьшить модуль - добавить дефицит после добавления, если было вызвано переполнение. Вот как бы вы добавили BCD, например, используя двоичное оборудование.
Хотя вы можете сделать добавление с помощью поплавка таким образом, есть вопрос о том , вы должны . Проблемы с использованием чисел с плавающей точкой для работы с целочисленными величинами хорошо известны, и я не буду их здесь перефразировать.
Как правило, сложение дробных дробей работает неявно с модулем 1,0, переполнение дробной части увеличивает целочисленную часть. Если мы интерпретируем точку как разделитель hours.minutes, то мы хотим, чтобы дробь переполнилась на 0,6. Для этого необходимо добавить дефицит 0,4 в соответствующее время.
который выдает следующий результат, с точностью до округления до того, что запрашивал ОП
Я оставил окончательное форматирование до двух знаков после запятой в качестве упражнения для читателя. 15 последних цифр во всей их красе иллюстрируют, почему использование поплавков - не лучший способ сделать это.
Кроме того, подумайте, что происходит, когда вы хотите включить секунды или дни. Два довольно более стандартных способа с плавающей запятой или с целым числом целых чисел, внезапно выглядят более разумными.
источник