I am looking for help in C++ converting an integer input into 24 hours format.
Suppose you build a scheduled time for airplanes from A (start) to B (end); The user is able to entry 4 different variables, such as the journey time of the airplane from A to B; the first airplane time; the last airplane time; and the frequency of traveling in one day.
The input would be like the following:
int journey_time;
int start_time;
int end_time;
int frequency;
cout << "Please enter your journey time:\n";
cin >> journey_time;
cout << "Please enter your start time:\n";
cin >> start_time;
cout << "Please enter your end time: \n";
cin >> end_time;
cout << "Please enter the frequency: \n";
cin >> frequency;
IMPORTANT to mention is that the user should type in the times as integer and the hours should be transformed in a 24 hour clock times
And this is where I am stucked; I was able to transform the integer into minutes but not into hours
so far I have this code
for (int total_min_start= start_time; total_min_start <= end_time; total_min_start +=frequency)
{
hs = total_min_start/100; // to get the hours
ms = total_min_start %100; // to get the minutes
x = (hs *60) + ms; // converted into minutes
h = ((x-ms)/60) * 100; <= this is where I am confused, I want here the reconversion of hours into to 24 hours format
t = h + ms; // this is the total time after reconversion
cout << t << "\t" << t + journey_time<< endl;
}}}
if I type in for journey time=15; start_time=0930; end_time= 1000 and frequency = 15 min, i get the following output (left) but I want this output (right)
WRONG OUTPUT RIGHT OUTPUT
930 945 930 945
945 960 945 1000
960 1000 1000 1015
I would be very very thankful for any kind of help or hint...
Thanks in advance
Okay lets unroll the loop and do each step separately.
First iteration:
// Loop initialization
total_min_start = 930;
hs = 930 / 100; // 9
ms = 930 % 100; // 30
x = (9 * 60) + 30; // 540 + 30 = 570
h = ((570 - 30) / 60) * 100; // (540 / 60) * 100 = 9 * 100 = 900
t = 900 + 30; // 930
// t + journey_time = 930 + 15 = 945
total_min_start += 15; // 945
So far so good, so we start the second iteration:
total_min_start = 945;
hs = 945 / 100; // 9
ms = 945 % 100; // 45
x = (9 * 60) + 45; // 540 + 45 = 585
h = ((585 - 45) / 60) * 100; // (540 / 60) * 100 = 9 * 100 = 900
t = 900 + 45; // 945
// t + journey_time = 945 + 15 = 960
total_min_start += 15; // 960
Ah here it seems we have a problem. The value in t is not the time in minutes, it's actually two separate values: Hours and minutes.
There are two ways to solve this: As soon as the user have entered the input, separate it into the two values, and keep track of the time in two separate variables.
The second way to solve it, and which I think is much easier, is to immediately after input convert the input into a single value, whose unit is the number of minutes after midnight. That is, if the user inputs 930 meaning 9:30 AM, you convert it into the value 570 (which is the number of minutes after midnight). Then work only with that value, increase and decrease as you wish, and only convert it back to your preferred format when presenting it to the user.
To help you with the conversions back and forth I suggest you have a couple of utility or helper functions: One for converting the timestamp into minutes past midnight, and one for converting the number of minutes past midnight into the timestamp. Then you could easily do something something like
cout << minutes_to_time(t) << '\t' << minutes_to_time(t + journey_time) << '\n';
Oh, and don't forget to test for wrapping around at midnight. Both ending up with t being exactly midnight, with t + journey_time being midnight, and with t being a little before midnight and t + journey_time being a little after midnight.
Create separate functions to convert minutes into 24 hour time format and vice versa.
auto get_24hr = [](int minutes){ return (minutes/60)*100 + (minutes%60);};
auto get_minutes = [](int time_24){return (time_24/100)*60+ (time_24 % 100);};
for (int total_min_start= start_time; total_min_start <= end_time; total_min_start +=frequency)
{
auto x = get_minutes(total_min_start); // converted into minutes
cout << get_24hr(x) << "\t" << get_24hr(x+journey_time) << endl;
}
Related
Input prompt asks for a starting time, and then a duration time where it returns two times: one time where they are added, and one where they are subtracted. I've gotten the basics of them, but when I try and do it for certain times (ex: 1:18 and 10:39) I get a negative error:
X Input of 1:18 10:39 : expected [11:57, 2:39] but found [11:57, -9:-21]
Here's the code that does the calculations:
int timeHours, timeMinutes, durHours, durMinutes;
cout << " Time: ";
cin >> timeHours;
cin.get();
cin >> timeMinutes;
cout << " Duration: ";
cin >> durHours;
cin.get();
cin >> durMinutes;
int time, duration, after, before, afterHours, afterMinutes, beforeHours, beforeMinutes;
const int MINUTES_IN_DAY = 60 * 24;
time = (timeHours * 60) + timeMinutes;
duration = (durHours * 60) + durMinutes;
after = time + duration;
before = time - duration;
afterHours = after / 60 % 12;
afterMinutes = after % 60;
beforeHours = before / 60;
beforeMinutes = before % 60;
cout << endl;
cout << durHours << ":" << setfill('0') << setw(2) << durMinutes << " hours after, and before, "
<< timeHours << ":" << timeMinutes << " is [" << afterHours << ":" << setw(2) << afterMinutes << ", "
<< beforeHours << ":" << setw(2) << beforeMinutes << "]" << endl;
The failed test above shows that the sum (1:18 + 10:39) works but the difference (1:18 - 10:39) does not work. It gives me "-9:-21" which should be able to be fixed by adding 24 hours, which is even what my assignment suggests: "This is easily done by adding a day (or two or three) to before when calculating the difference" but when I add 1440 (60 * 24) to the "before" initialization:
before = (time - duration) + MINUTES_IN_DAY;
and convert back from minutes to normal time I get 14:39, which is 2:39, but in 24 hour form, not 12 (incidentally it also makes all the other tests which were passing now failing). I think there's some hint when it says "by adding a day (or two or three) since obviously 1440 is different from 1440*2 or *3, but I'm not seeing it and I have to be missing something obvious. I know I'll have to fix it for midnight as well but I'll change that later. If anyone knows what I'm trying to explain, I'd really appreciate it
Usually, when working with times/dates it's easier to make yourself a function to convert a human-readable date to milliseconds or seconds (and vice versa) and build up from that base. In your case, you'll just add/subtract the two time-marks in seconds for example:
long long time = toSec(timeHours, timeMinutes, timeSeconds);
long long duration = toSec(durHours, durMinutes, durSeconds);
string after = toDate(time + duration);//somethig like 12:34:00 (hh:mm:ss)
string before = toDate(time - duration);
however, putting effort in making such conversion functions would be an overcomplication if all you use them for is a one-time calculation.
( like you suggested to add MINUTES_IN_DAY) to solve the negative values problem you can use the %MINUTES_IN_DAY to avoid the overflow caused by adding MINUTES_IN_DAY to a positive value
before = ((time - duration)+MINUTES_IN_DAY)%MINUTES_IN_DAY;
I wrote a program to solve the exercise below. I got my hours and minutes right, but I cannot get my seconds right.
In order to save disk space Time field in the directory entry is 2
bytes long. Distribution of different bits which account for hours,
minutes and seconds is given below:
15 14 13 12 11|10 9 8 7 6 5| 4 3 2 1 0
H H H H H| M M M M M M| S S S S S
Write a C++ Program that take input two-byte time entry and
appropriately separates hours, minutes and seconds using suitable
bitwise operators.
#include<iostream>
using namespace std;
int main()
{
unsigned int hours, mins, secs;
unsigned int time;
cout << "enter time ";
cin >> time;
hours = (time >> 11);
mins = ((time << 5) >> 10);
secs = ((time << 11) >> 11);
cout << hours << " " << mins << " " << secs << endl;
return 0;
}
To get the minutes, I shift the input to the left by 5 positions, hoping to eliminate all the H bits, and then shift to the right by 10 positions to eliminate all the S bits and have the M bits at the rightmost position.
Similarly for the seconds.
However, if I enter 445 I expect the result to be 13 minutes and 29 seconds, but the program outputs 0 13 445.
Why do the hours and minutes appear to come out correctly, but not the seconds?
secs = time & 0x1F; // This should give the 5 bits you're expecting for seconds.
You are assuming that the size of unsigned int is 16 bit but it is normally implemented as 32bit integer on nowadays machines.
If you would use uint16_t for the variable time instead it should work.
To use uint16_t include the header stdint.h.
#include <iostream>
#include <stdint.h>
using namespace std;
int main()
{
uint16_t hours, mins, secs;
uint16_t time = 445;
hours = (time >> 11);
mins = ((time << 5) >> 10);
secs = (time << 11);
secs >>= 11;
cout << hours << " " << mins << " " << secs << endl;
return 0;
}
(Tested on QT 5.5)
You should zero the bits that don't correspond to the part of time you are looking at. I will use binary literals (which are available in C++14), but comment the equivalent hex literals.
struct time {
time(unsigned = 0); // also default constructs
unsigned hours;
unsigned mins;
unsigned secs;
}
time::time(unsigned packed) :
hours((packed & 0b1111100000000000) >> 11), // 0xF800
mins ((packed & 0b0000011111100000) >> 5 ), // 0x07E0
secs ((packed & 0b0000000000011111) ) // 0x001F
{ }
#include<iostream>
std::ostream& operator<< (std::ostream& os, time t) {
return os << t.hours << " " << t.mins << " " << t.secs;
}
int main()
{
time t(445);
std::cout << t << std::endl;
return 0;
}
The task given is impossible, because 6 bits are required for both the minutes and the seconds. You have alotted 5 bits for the seconds.
2^5=32
2^6=64
Using this scheme, 17 bits are required to represent the time.
Hello I am a begineer so please be nice :)..
In C++, if I have a float like 12.5 or 13.25, how can I convert this to show as 12:30 and 13:15?
Thank you so much.
float time = ...;
Simly casting the float to an int will chop off the fractional part, leaving you with the hours.
int hour = static_cast<int>(time);
If you subtract the hours, then all that's left is the minutes as fractions of an hour. If you multiply this by 60, you get the remainder in minutes. Again, cast to an int to chop off the seconds, leaving only minutes.
int minute = static_cast<int>((time-hour)*60);
Then display the hours, and a colon. To display the minutes properly, tell it to always use a width of 2 characters, and fill in the blanks with a '0'. This makes it say 02 instead of just 2.
std::cout << hour << ':' << std::setw(2) << std::fill('0') << minute;
As with any problem, you need to break it down into its component parts and attack each one separately.
What you have:
A floating-point number of hours.
What you need:
To print the integer number of hours.
To print a ":"
To print the fractional number of hours as a proportion of 60 minutes.
So, now, we can address each part of the problem.
Let's say the input is:
const float time = 13.25;
The first part is quite easy — truncating a floating-point variable can be done using the mathematical floor function, but all you really need to do is cast to int to get the same effect:
std::cout << (unsigned int)time;
The second part is also really easy:
std::cout << ':';
The third part takes a little more work. We need to discard everything but the fractional part. We can do that by subtracting the integer part:
time - (unsigned int)time
Then we must transform the value so that instead of being a proportion of the range [0.00,1.00), it's a proportion of the range [0,60), simply by multiplying by 60:
60 * (time - (unsigned int)time)
We're left with:
const float time = 13.25;
std::cout << (unsigned int)time;
std::cout << ':';
std::cout << 60 * (time - (unsigned int)time);
// result: 13:15
(live demo)
For a general solution, we also want to show a leading zero if there's only one digit:
const float time = 12.10;
std::cout << (unsigned int)time;
std::cout << ':';
std::cout << std::setw(2) << std::setfill('0');
std::cout << 60 * ((time - (unsigned int)time) / 100);
// result: 12:06
In reality, to avoid rounding errors and possible overflows, you'd drop the float altogether and simply store integer minutes:
const unsigned int time_mins = (12*60) + 6;
std::cout << (time_mins / 60);
std::cout << ':';
std::cout << std::setw(2) << std::setfill('0');
std::cout << (time_mins % 60);
// result: 12:06
(live demo)
Or, y'know, use an actual time/date type.
I'm taking a C++ class, as I just started my first year of college and it has been destroying me. I have been attempting for hours to do my homework but can't come to a solution.
My assignment is to make a C++ program that when given minutes will tell you years and days.
We have been using float and cout and cin in class and some % and / structures which are foreign to me. If someone could help that would be great because I lost all hope at this point.
#include <iostream>
using namespace std;
float = minutes
float = hours
float = days
float = years
float = seconds
int main()
{
using namespace std;
int days, years, minutes, hours, seconds;
cout << "Please Enter Minutes" << endl;
cin >> minutes;
days = input_minutes / 60 / 60 / 24;
hours = (input_minutes / 60 / 60) % 24;
minutes = (input_minutes / 60) % 60;
seconds = input_minutes % 60;
cout << days << " seconds = " << years << " years ";
cin.get();
cin.get();
return 0;
}
I took the liberty to look at the code that you have into the comment box;
first thing :
Declare a variable to store the input value or save the result of a computation
int days; //<--- declaration of a int variable called days
so this in line I don't know what you were trying to do but float = minutes float = hours float = days float = years float = seconds
Please don't do it
second thing:
Don't repeated `using namespace std` twice. Therefore remove it from the `int main` function.
Third :
your computation is kinda OFF, try to solve mathematically then code it.
your code should look like that: (This is not the answer)
#include <iostream>
using namespace std;
int main()
{
int days, years, input_minutes, hours, seconds,minutes;
cout << "Please Enter Minutes" << endl;
cin >> input_minutes;
days = input_minutes / 60 / 60 / 24;
hours = (input_minutes / 60 / 60) % 24;
minutes = (input_minutes / 60) % 60;
seconds = input_minutes % 60;
cout << days << " seconds = " << years << " years ";
system("Pause");
return 0;
}
I can give you a little help on what each of those means. Here are the non-super technical definitions.
A float is an integer that can have decimal places.
cout Will output the value next to <<
cin will store a value from an input (cin >> x) will store the user input in x.
% is the modulus character. It will return the remainder after the division of two numbers. 3%2 will return 1.
/ is just simple, plain old, division.
Joe, I think we shouldn't do that job for you, and this is not exactly a "technical" question. Considering this, I will try to give you some ideas.to get some extra scores:
1 - take the user input, "the number of minutes" from command line args, like:
int main(int argc, char *argv[]) {
int num_mim = atoi(argv[1]);
2 - to take the number of years do int num_years = num_mins / (60 * 24 * 365);
(not taking into account leap years)
3 - to take the number of days do int num_days = num_mins % (60 * 24 * 365) / 60 / 24;
of course simplify the operations by performing the multiplications and divisions that can be made by hand if you want.
% is the modulos operator, it gives you the remainder of the dvision, here we use it to get the remainder of minutes from the years cound and express it in days.
Now it is up to you, look for additional sources of info and assemble your homework.
I just finished my change calculator (Calculates change based on cost of purchase and cash given). I was testing it to see if it works and found one bug. Whenever the amount of pennies to be given is exactly one, it says it is 0. I went through the code and did the math manually off the code I wrote (without running it) and it looks like it should work. If you want to test this yourself just put in 0 as the cost of the purchase and 36.91 as the cash given. (This means the change is 36.91 and it should be 1 twenty, 1 ten, 1 five, 1 half dollar, 1 quarter, 1 dime, 1 nickel, and 1 penny [but it says 0 pennies].
Due note: I am very new to C++ and know VERY little
Here is the code:
/*This program simulates a situation at the register where someone pays with cash
and the cashier needs to know how much change and of which coins he or she needs to give.
Written by Jay Schauer
*/
//Data Declarations
#include <iostream>
#include <cstdint>
int main()
{
using namespace std;
double cost; //Stores cost of purchase
cout << "Input cost of purchase (in USD)" << endl;
cin >> cost;
double cash; //Stores cash that pays for purchase
cout << "Input cash given (in USD)" << endl;
cin >> cash;
double changet = cash - cost; //Stores the change,
the t is for temporaary because I use a different change variable later
cout << "Change to be given is " << changet << " in..." << endl;
//Also, I thought this was pretty clever since doubles apparantly can't be used
//with modulus (it gave me an error),
//so I figured I just multiply it by 100 and multiply all the divisions by 100 also
changet *= 100;
int change = changet; //Converts changet to an integer to be used with the modulus
int coins; //Stores the amount of "coins" to be given as change
coins = change / 2000;
cout << coins << " twenty dollar bills" << endl;
change = change % 2000;
coins = change / 1000;
cout << coins << " ten dollar bills" << endl;
change = change % 1000;
coins = change / 500;
cout << coins << " five dollar bills" << endl;
change = change % 500;
coins = change / 100;
cout << coins << " one dollar bills" << endl;
change = change % 100;
coins = change / 50;
cout << coins << " half dollars" << endl;
change = change % 50;
coins = change / 25;
cout << coins << " quarters" << endl;
change = change % 25;
coins = change / 10;
cout << coins << " dimes" << endl;
change = change % 10;
coins = change / 5;
cout << coins << " nickels" << endl;
change = change % 5;
//There is one problem that I can't figure out
//If the number of pennies to be given for change is exactly 1,
//it says 0 for the number of pennies to be given as change
coins = change / 1;
cout << coins << " pennies" << endl;
system("pause");
return 0;
}
Unfortunately you've stubled across one of the common problems with using double and floating point values. They aren't exact. They are good enough for rock and roll, but when you want exact, wellll....
OK so you have 36.91... sort of. It's really something like 36.90999999999.
You multiply it by 100 and get 3690.999999999.
You convert it into an integer and get truncated to 3690. The fraction is completely discarded.
You should be able make it work here by rounding .
int change = std::round(changet);
This code is relying on integer division, when you should be using floating-point division. In short, you are truncating the decimal portions of your answers.
Let's step through, using your input of $36.91. First, with $20 bills:
coins = change / 2000; -> coins = 3691 / 2000; -> coins = 1.8455;
since we are dealing with integers, this falls into integer division and coins is actually set to 1. One $20 bill is due as change.
Moving on, for $10 bills:
change = change % 2000; -> change = 3691 % 2000; -> change = 1691;
coins = change / 1000; -> coins = 1691 / 1000; -> coins = 1.691;
again, this falls into integer division, so 1.691 is truncated and coins is set to 1. The program will indicate that one $10 bill is due.
Now, for $5 bills...
change = change % 1000; -> change = 1691 % 1000; -> change = 691;
coins = change / 500; -> coins = 691 / 500; -> coins = 1.382;
The decimal component of 1.382 is, again, dropped, and coins is set to 1. That's one $5 bill.
change = change % 500; -> change = 691 % 500; -> change = 191;
coins = change / 100; -> coins = 191 / 100; -> coins = 1.91;
1.91 is truncated to 1. That's one $1 bill.
change = change % 100; -> change = 191 % 100; -> change = 91;
coins = change / 50; -> coins = 91 / 50; -> coins = 1.82;
Again, that's truncated. 1.82 is cast to an integer set to 1. One half-dollar.
change = change % 50; -> change = 91 % 50; -> change = 41;
coins = change / 25; -> coins = 41 / 25; -> coins = 1.64;
One quarter.
change = change % 25; -> change = 41 % 25; -> change = 16;
coins = change / 10; -> coins = 16 / 10; -> coins = 1.6;
One dime.
change = change % 10; -> change = 16 % 10; -> change = 6;
coins = change / 10; -> coins = 6 / 5; -> coins = 1.2;
One nickel.
change = change % 5; -> change = 6 % 5; -> change = 1;
coins = change / 1; -> coins = 1 / 1; -> coins = 0.9999999999999;
Zero pennies.
The reason for this is how binary arithmetic handles division. There is a loss of precision that is causing 0.9999999 to be calculated, which when truncated will result in zero pennies.
Your solution: Since dividing something by 1 yields that same something (identity), take coins = change / 1; out of your program.
Also, search for an article on floating point arithmetic.