Link to home
Start Free TrialLog in
Avatar of troy24
troy24

asked on

'double' variable problem??????

I am creating a service report and the users have to enter in the time they started to the time they finished and I want to calculate the amount of hours they have worked.  The method I am using seems to work the odd time but I am having trouble getting it to work all the time.  I am using double variables and I am not sure if I should be using them. I am also changing the time into 24 hr clock if the starttime is larger than the endtime.
eg. starttime  11.00  endtime 2.00->14.00
This works all the time but it is when you subtract the time such as 1.15 to 2.00, you get 0. 45  but I want it to be .75 because you have worked 3/4 of an hour.  I am only doing it in 15 minute intervals so I didn't think it woul be that difficult.  This is how I am doin it.
if (m_hourswork==0.45) //45 minutes worked
    m_hourswork=0.75;
if m_hourswork==0.15)  //15 minutes worked
   m_hourswork=0.25)
I do this for all 15 min intervals and every hour upto 10 hours because no one will work more than 10.  The method I am using seems to work from time to time so I think it may be the 'double' varibles I am using.

Thank You for the help!!
Greatly Needed
Avatar of troy24
troy24

ASKER

Edited text of question
answer coming.
>> when you subtract the time such as 1.15 to 2.00, you get 0. 45  but I want it to be .75
You aren't being consistent in your interpretatation.  If 1.00 represents an hour then 0.75 represents 3/4 of an hour or 45 minutes.  That is consistent.  But then 1.15 does not represent and hour an 15 minutes.  It represents and hour and 15/100 of an hour, about 9 minutes.  Thus
2.00 (2 hours) minus 1.15 is 0.85 or 85/100 of an hour or about 51 minutes, which is correct.

Thus you can do the math this way.  The integer portion is the number of whole hours and the decimal portion is the fractional part of an hour--not the minutes.  but there is a better way.

continues.
What I would do is use a serial time for the math.  a serial time represents the time using a single number, unlike hours and minutes that use seconds.   The serial time scale starts at 0 at some time that you decide and then increases by one for each of the smallest units you want to measure.  Thus if you need accuaracty to the minute, you might start the serial time scale at 0 at midnight, then 1 would be 1 minute after midnight (12:01 PM).  Then 2 would be one minute later and so on. 1:15 PM, would then be 795 (13*60+15--more on that later)  If you wanted accuracy to the second, you would dot he same thing, but each successive number indicates an additional second, not a minute.

The advantage to the serial time is that you can do math using the ordinary +,- and even * and / operators.  Thus to find the difference between two serial times you can just subtract them with -.
Now to make this work, you need to be able to convert between "ordinary" times and serial times--because no one wants to enter serial times into the computer.  But that is pretty easy.

Say you are doing it to the minute.  Then the formula is the
T = H*60 + M
where H is the hours (on a 24 hour clock) and M is the minutes.  For a second of accuracy you would use
T = H*60*60 + M *60 + S

To convert back you would use

H = Trunc(T / 60)
M = T - H*60

Let me know if you have questions.
More time math.  I worked on an answer from 6:56 to 7:16.  that is 20 minutes.

If you don't like the answer or don't understand it you should at least post a comment saying why.

you can check if the function difftime is available. in combination with mk_time, you create a solution with standard functions (at least on Unix)
difftime() is always available, it's part of the C standard, which is a base document for the C++ standard.

troy, it's a dumb idea to use a floating point representation for what are inherently integer quantities.  Floating point arithmetic is inexact and will allow errors to creep into your accounting.  Seeing as you asked this in the C++ section, and sound like you want to roll your own, maybe you'd prefer to cook up a class which exhibits the behaviour you want using, say, an unsigned char each to store hours, minutes or seconds, and appropriate member functions to completely hide how the time is stored from the outside world.  If you use MFC, examine CTime.  And be a good chap, tell nietod what was up with his answer, because it looked fine to me.
difftime uses serial times.  It just subtracts the two serial times and coverts the result to floating point.  The mktime() procedure is used to calculate the serial times it uses.  However that serial time can be used to calculate the difference in times between days.  That is, it is on a much longer scale.
Avatar of troy24

ASKER

Thanks for eveyones help. Sorry if I caused any problems but I am new at this.
Also do not do this:
double hours_worked;
if (hours_worked == 0.45) {
.
}

do not use ==, and != with doubles.  Because of rounding and inexactness you are likely to get some unexpected behavior
ASKER CERTIFIED SOLUTION
Avatar of rbr
rbr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
rbr, do you read these questions?
troy, I spent a lot of time explaining this to you (for a measley 20 pts).  You rejected my answer without a word and then accepted rbr's "answer" which was a tiny subset of what I said.  with a littlle of what danny_pa said thrown in.