Problem with integers

K

Kelly Goode

I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30? I should get
back 2 hours and 30 minutes but instead I get 2 hours and 29 minutes.

#include <stdio.h>
int main(void)
{

double elapsed_time;
int hours;
int minutes;

printf("Enter hours (hh.mm): ");
scanf("%lf", &elapsed_time);

//take the integer of 2.30 to get # of hours which is 2
hours = elapsed_time;

// Ex. (2.30 - 2) = 0.3 ===> (0.3 * 100) = 29 !?!?!?!?!?!?!?!?!?
minutes = (elapsed_time - hours) * 100;

printf("\nYou entered an elapsed time of %d hours and %d
minutes.\n", hours, minutes);
getch();

//Output for 2.30 is always 2 Hours and 29 minutes

return 0;
}
 
C

Chris Torek

I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30?

It is not a problem with integers, but rather with floating point.
See the comp.lang.c FAQ, section 14.
// Ex. (2.30 - 2) = 0.3 ===> (0.3 * 100) = 29 !?!?!?!?!?!?!?!?!?

2.30 is actually about 2.2999999523. Subtracting 2 gives 0.2999etc.,
and multiplying by 100 gives 29.999etc., which is of course 29 when
converted to "int".
 
C

Christian Bau

"Kelly Goode said:
I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30? I should get
back 2 hours and 30 minutes but instead I get 2 hours and 29 minutes.

2.30 is not two and thirty hundredths; it is a number close to that
because C uses binary floating point numbers and not decimal floating
point numbers. It may be slightly larger or slightly smaller. Check what
your calculations do if it is just a tiny bit less than two and thirty
hundredths.
 
C

Chris Torek

2.30 is actually about 2.2999999523. ...

Minor correction: I used an IEEE float, instead of an IEEE double.
The latter gives a number around 2.2999999999999998224 as the value
closest to 2.30.

The rest of the article stands. :)
 
X

x-pander

Kelly Goode said:
I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30? I should get
back 2 hours and 30 minutes but instead I get 2 hours and 29 minutes.

#include <stdio.h>
int main(void)
{

double elapsed_time;
int hours;
int minutes;

printf("Enter hours (hh.mm): ");
scanf("%lf", &elapsed_time);

//take the integer of 2.30 to get # of hours which is 2
hours = elapsed_time;

// Ex. (2.30 - 2) = 0.3 ===> (0.3 * 100) = 29 !?!?!?!?!?!?!?!?!?
minutes = (elapsed_time - hours) * 100;

what happens here is an implicit conversion:
minutes = (int)((2.3 - 2) * 100)

which actually is equivalent to:
minutes = (int)(30.0 + EPSILON)

where EPSILON is some (implementation dependant) value that may be positive,
negative or 0.
If it is negative than conversion to int above yields 29.
That is because conversion from float to integer type is defined as
truncation of fractional part.

So, to make it work write:
minutes = 0.5 + (elapsed_time - hours) * 100;

or alternatively, if you use c99 compilant compiler add:
#include <math.h>
and write:
minutes = round((elapsed_time - hours) * 100);
 
K

Keith Thompson

Kelly Goode said:
I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30? I should get
back 2 hours and 30 minutes but instead I get 2 hours and 29 minutes.

#include <stdio.h>
int main(void)
{

double elapsed_time;
int hours;
int minutes;

printf("Enter hours (hh.mm): ");
scanf("%lf", &elapsed_time);

//take the integer of 2.30 to get # of hours which is 2
hours = elapsed_time;

// Ex. (2.30 - 2) = 0.3 ===> (0.3 * 100) = 29 !?!?!?!?!?!?!?!?!?
minutes = (elapsed_time - hours) * 100;

printf("\nYou entered an elapsed time of %d hours and %d
minutes.\n", hours, minutes);
getch();

//Output for 2.30 is always 2 Hours and 29 minutes

return 0;
}

There is no getch() function in standard C; it's probably something
specific to your operating system. If you want to call it (for
whatever reason), you should include the header that declares it.

You're trying to store the value 2.30 in an object of type double.
This value cannot be represented exactly in a binary floating-point
type. In the statement

minutes = (elapsed_time - hours) * 100;

you're computing (2.30 - 2) * 100 as a double value, which yields an
approximation to 30.0, but apparently you're getting something
something like 29.9999999999. Assigning this value to minutes, which
is an int, gives you 29, discarding the 0.9999999999.

You're asking the user to enter a real number which you're going to
interpret as a pair of integers. Instead, try reading it as a pair of
integers. Let the user enter "2:30", and extract the values 2 and 30
from the input, not from a floating-point value.
 
B

Barry Schwarz

I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30? I should get
back 2 hours and 30 minutes but instead I get 2 hours and 29 minutes.

This is a strange way to represent time but that is a different issue.
#include <stdio.h>
int main(void)
{

double elapsed_time;
int hours;
int minutes;

printf("Enter hours (hh.mm): ");
scanf("%lf", &elapsed_time);

2.3 cannot be represented exactly in binary. On your system, the
closest approximation is apparently 2.2999.... Now work out the
arithmetic and see what you get.
//take the integer of 2.30 to get # of hours which is 2
hours = elapsed_time;

// Ex. (2.30 - 2) = 0.3 ===> (0.3 * 100) = 29 !?!?!?!?!?!?!?!?!?
minutes = (elapsed_time - hours) * 100;

printf("\nYou entered an elapsed time of %d hours and %d
minutes.\n", hours, minutes);
getch();

//Output for 2.30 is always 2 Hours and 29 minutes

return 0;
}



<<Remove the del for email>>
 
M

Martin Ambuhl

Kelly said:
I have a problem with some simple math operations resulting in the wrong
integer. Why am I getting the wrong integer back for 2.30? I should get
back 2 hours and 30 minutes but instead I get 2 hours and 29 minutes.

The number of posts we get from people who don't understand floating
point arithmetic is almost beyond counting. That's why your question
was long ago answered in the FAQ, which you should have checked before
posting. Even more, it has been answered countless times in all those
countless threads by those clueless ones that preceded you. Try the
following code on your implementation and think about the result:

#include <stdio.h>
#include <float.h>

int main(void)
{

double elapsed_time = 2.30;
double dminutes;
int hours;
int minutes;
hours = elapsed_time;
dminutes = (elapsed_time - hours) * 100;
printf
("minutes with purposeful precision beyond true\n"
" significance: %.*g\n",
DBL_DIG + 4, dminutes);
minutes = dminutes + 0.5;
printf("\n2.30-> %d:%d\n", hours, minutes);
return 0;
}

minutes with purposeful precision beyond true
significance: 29.99999999999998224
2.30-> 2:30

[OP's code]
 
C

CBFalconer

Kelly said:
I have a problem with some simple math operations resulting in the
wrong integer. Why am I getting the wrong integer back for 2.30?
I should get back 2 hours and 30 minutes but instead I get 2 hours
and 29 minutes.

As you should. You should fix your program instead - see below.
#include <stdio.h>
int main(void)
{
double elapsed_time;
int hours;
int minutes;

printf("Enter hours (hh.mm): ");
scanf("%lf", &elapsed_time);

//take the integer of 2.30 to get # of hours which is 2
hours = elapsed_time;

// Ex. (2.30 - 2) = 0.3 ===> (0.3 * 100) = 29 !?!?!?!?!?!?!?!?!?
minutes = (elapsed_time - hours) * 100;

/* Here is your basic error */
minutes = ((elapsed_time - hours) + 0.5) * 100;
printf("\nYou entered an elapsed time of %d hours and %d
minutes.\n", hours, minutes);

illustrating why you should keep line length under 72 char. My
suggested format:

printf("\nYou entered an elapsed time of %d hours"
" and %d minutes.\n", hours, minutes);

What can this possibly do for you? Just run it in a command line
window. Don't fight the silly IDE.
//Output for 2.30 is always 2 Hours and 29 minutes
return 0;
}

Floating point arithmetic is not exact arithmetic. Assigning
29.9999999999999 to an int results in 29.
 
C

Chris Croughton

As you should. You should fix your program instead - see below.

/* Here is your basic error */
minutes = ((elapsed_time - hours) + 0.5) * 100;

Why would he want to add 50 to the minutes? I think you meant:

minutes = (elapsed_time - hours) * 100 + 0.5;

Chris C
 
K

Kevin D. Quitt

You need to read and understand

ftp://ftp.quitt.net/outgoing/goldbergFollowup.pdf
 
C

CBFalconer

Chris said:
Why would he want to add 50 to the minutes? I think you meant:

minutes = (elapsed_time - hours) * 100 + 0.5;

Yup - well caught. Naughty keyboard. A cow flew by. Dang skeeters.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,183
Messages
2,570,969
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top