С++ конвертирует десятичные часы в часы, минуты и секунды

У меня есть некоторое количество миль и скорость в милях в час, которую я преобразовал в количество часов, необходимых для преодоления этого расстояния с этой скоростью. Теперь мне нужно преобразовать это десятичное число в часы, минуты и секунды. Как мне это сделать? Мое лучшее предположение прямо сейчас:

double time = distance / speed;
int hours = time; // double to integer conversion chops off decimal
int minutes = (time - hours) * 60;
int seconds = (((time - hours) * 60) - minutes) * 60;

Это правильно? Есть лучший способ сделать это? Спасибо!


person Jared    schedule 14.12.2009    source источник


Ответы (4)


Я не знаю функций С++ навскидку, однако этот «псевдокод» должен работать.

double time = distance / speed;
int hours = time;
double minutesRemainder = (time - hours) * 60;
int minutes = minutesRemainder;
double secondsRemainder = (minutesRemainder - minutes) * 60;
int seconds = secondsRemainder;

Исправлено отсутствие необходимости в полу.

Что касается комментария о том, что это не работает для отрицательных времен, у вас не может быть отрицательного расстояния в физике. Я бы сказал, что это будет ошибка пользовательского ввода, а не ошибка кодера!

person Brett Allen    schedule 14.12.2009
comment
Для положительных time floor там совершенно лишнее. Для отрицательного time это неверно. - person avakar; 15.12.2009
comment
Ах, я делаю это, чтобы быть в безопасности с двойным преобразованием в целое число, никогда не уверен, что оно округляет или отбрасывает десятичное число. Остаток минут — это число меньше 1, что представляет собой десятичную долю часа (0,25 = 15 минут). Умножение на 60 превращает его в правильные минуты (0,25 * 60 = 15). - person Brett Allen; 15.12.2009
comment
avakar, у вас не может быть отрицательного времени при измерении скорости, если только вы не нарушаете законы физики. - person Brett Allen; 15.12.2009
comment
На самом деле отрицательные времена возникают в физических расчетах все время. - person avakar; 15.12.2009
comment
... а также отрицательные скорости. - person avakar; 15.12.2009

Я не знаю, лучше ли это... на самом деле я не уверен, что это правильно, поскольку я не проверял это, но я бы сначала преобразовал часы в общее количество секунд, а затем преобразовал бы это обратно в часы/минуты/секунды. Это будет выглядеть примерно так:

int totalseconds = time * 3600.0;

// divide by number of seconds in an hour, then round down by casting to an integer.
int hours = totalseconds/3600;

// divide by 60 to get minutes, then mod by 60 to get the number minutes that aren't full hours
int minutes = (totalseconds/60) % 60;  

// use mod 60 to to get number of seconds that aren't full minutes
int seconds = totalseconds % 60;  
person Al Crowley    schedule 14.12.2009
comment
Время указано в часах, поэтому общее количество секунд будет временем * 3600,0, а количество часов будет равным полу (всего секунд / 3600). Вы далеко... - person Brett Allen; 15.12.2009
comment
Я только что исправил код для умножения на 3600, как заметил Aequitarum. Если мой C-foo не вышел из строя, преобразование часов должно быть прямо сейчас, поскольку приведение к целому числу автоматически возьмет слово. Возможно, это было бы более читабельно с явным вызовом floor(). Если бы это был производственный код, предназначенный для долгосрочного обслуживания, вероятно, было бы неплохо сделать его как можно более явным. - person Al Crowley; 15.12.2009

Я бы сказал, что ты прав. :-)

Хотя я должен добавить, что если метод, подобный представленному Aequitarium Custos, более удобочитаем или предпочтителен для вас, во что бы то ни стало используйте этот метод. Иногда проще вычислять элементы данных по одному и вычислять следующий из того, который вы только что вычислили, чем использовать абсолютную формулу, всегда начинающуюся с ваших первых данных.

В конце концов, пока ваша математика верна (а я думаю, что это так), вам решать, как вы хотите написать код.

person Platinum Azure    schedule 14.12.2009

а. Проверьте, не равна ли скорость 0

б. это плохое программирование - помещать двойное значение в int IMHO. использовать пол (при условии, что время положительное...)

в. если скорость и расстояние целочисленные - результат по времени будет неверным...

д. @Aequitarum Custos получил это сразу после редактирования...

person Dani    schedule 14.12.2009
comment
Даже если вы используете floor, вы все равно помещаете двойное число в целое число. - person avakar; 15.12.2009