Thread: Strange arithmetic results

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    7

    Strange arithmetic results

    I´m seeing arithmetic results that are baffling me.
    In my header file, I declare the following:

    Code:
    #define MAX_CHILDREN 200
    #define APPLES_PER_CHILD 25
    In my code, I have an attribute to count the number of children served with apples:
    Code:
    long children_served;
    In my tests, number of children served is coming in with the value of 1. But I get strange results from the following printfs:
    Code:
    printf("The maximum number of children served is %d\n", MAX_CHILDREN);
    printf("Apples served per child: %d\n", APPLES_PER_CHILD);
    printf("Number of children unserved: %ld\n", (MAX_CHILDREN - children_served));
    printf("Number of apples needed to serve unserved children: %ld\n", (MAX_CHILDREN - children_served) * APPLES_PER_CHILD);
    The first three printouts are as expected. But the last one is coming in with the wrong value!! It shows 619, while it should be 4975!
    Code:
    The maximum number of children served is 200
    Apples served per child: 25
    Number of children unserved: 199
    Number of apples needed to serve unserved children: 619
    Any ideas what´s going on here? ANd yes, I´ve tried casting, since that´s the only thing I thought could be wrong with the code.

    Thanks

  2. #2
    Here we go again...
    Join Date
    Sep 2011
    Location
    San Diego
    Posts
    102
    I ran this and it prints out correctly. Do you have some other code in there that might giving you problems?

    Code:
    #define MAX_CHILDREN 200
    #define APPLES_PER_CHILD 25
    
    int main(void)
    {
        long children_served = 1;
    
        printf("The maximum number of children served is %d\n", MAX_CHILDREN);
        printf("Apples served per child: %d\n", APPLES_PER_CHILD);
        printf("Number of children unserved: %ld\n", (MAX_CHILDREN - children_served));
        printf("Number of apples needed to serve unserved children: %ld\n", (MAX_CHILDREN - children_served) * APPLES_PER_CHILD);
    
        return 0;
    }

  3. #3
    Registered User
    Join Date
    Feb 2011
    Posts
    13
    Worked for me!

  4. #4
    Registered User
    Join Date
    Jul 2011
    Posts
    7
    Rmatze:

    Yes, there´s a lot of code between the declaration of the children_served variable and the logs. However, what´s interesting is that everything gets printed out correctly until the last printf. That is, the compiler calculates correctly that MAX_CHILDREN - children_served equals 199. Where it goes wrong is in the next line, where it multiplies that result by APPLES_PER_CHILD (whose value is 25). How is it that the result of that multiplication is 619? That´s what I don´t get.

  5. #5
    Registered User
    Join Date
    Feb 2011
    Posts
    13
    looks like your only choice is to just replace the variables with their values in the printf.
    example: printf("%d",(200 - children_served)*APPLES_PER_CHILD) //i don't know why you needed a long int

    that should be an easy way to find the problem
    Last edited by timmmay; 10-21-2011 at 11:46 AM.

  6. #6
    Here we go again...
    Join Date
    Sep 2011
    Location
    San Diego
    Posts
    102
    Try checking the value of the variables before the line that is giving you troubles. Something like this:

    Code:
    printf("MAX_CHILDREN: %d, children_served: %d, APPLES_PER_CHILD: %ld\n", MAX_CHILDREN, children_served, APPLES_PER_CHILD);

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Casting is very rarely the right answer. It's basically telling the compiler you know better than it does, which is rarely true.

    You need to post the smallest compilable code that exhibits the error, so we can run/verify it on our systems and help you fix it.

  8. #8
    Registered User
    Join Date
    Jul 2011
    Posts
    7
    Ok, I´ll tell you guys what I did to make it work. But first let me add that I began by following Timmmay´s suggestion. I substituted the (MAX_CHILDREN - children_served) calculation with a literal to narrow down where the error was occurring:

    Code:
    printf("The maximum number of children served is %d\n", MAX_CHILDREN);
    printf("Apples served per child: %d\n", APPLES_PER_CHILD);
    printf("Number of children unserved: %ld\n", (MAX_CHILDREN - children_served));
    printf("Number of apples needed to serve unserved children: %ld\n", 199 * APPLES_PER_CHILD);
    So the only thing I changed was the last line. Believe it or not, I was still getting the following results:

    Code:
    The maximum number of children served is 200
    Apples served per child: 25
    Number of children unserved: 199
    Number of apples needed to serve unserved children: 619
    So it appears that the problem is with the pre-processor constant multiplication 199 * APPLES_PER_CHILD.

    What was the work-around I did? I created two new variables, and initialized them to the constants, as below:

    Code:
    long children_served;
    long maximum_num_children = MAX_CHILDREN;
    long apples_per_head = APPLES_PER_CHILD;
    I then used those new variables in the logs:
    Code:
    printf("The maximum number of children served is %ld\n", maximum_num_children);
    printf("Apples served per child: %ld\n", apples_per_head);
    printf("Number of children unserved: %ld\n", (maximum_num_children - children_served));
    printf("Number of apples needed to serve unserved children: %ld\n", (maximum_num_children - children_served) * apples_per_head);
    The results came out correct this time:
    Code:
    The maximum number of children served is 200
    Apples served per child: 25
    Number of children unserved: 199
    Number of apples needed to serve unserved children: 4975
    Creating those two new variables and populating them with the constants would seem to me to be unnecessary, and kind of destroys the purpose of pre-processor statements in your code. But that´s the only solution I found to the problem. Something´s happening with that pre-processor statement that´s causing it to produce strange results. So I found a solution, but I would greatly appreciate being able to understand what went wrong.

    Thanks everyone for the posts.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Out of interest, which compiler are you using?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Jul 2011
    Posts
    7
    Salem, I´m not sure. I´ll have to ask about that on Monday. Seems like something in the way the compiler is pre-processing those directives, huh?

  11. #11
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Hmm, may be the fact that printf waits for a long, while 199*25 yields an int.
    Devoted my life to programming...

  12. #12
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    If that's what you had to do to fix the problem then whatever compiler you're using is junk.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #13
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by iMalc View Post
    If that's what you had to do to fix the problem then whatever compiler you're using is junk.
    Not necessarily. In LP64 systems such as Linux, int is 32-bit and long is 64-bit. ( Picky me )
    Devoted my life to programming...

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Hmm, may be the fact that printf waits for a long, while 199*25 yields an int.
    True, but the first result had a long variable to begin with to force the promotion to long.

    Also, the incorrect result doesn't look like any kind of endian-swapped or truncated proper result.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by Salem View Post
    > Hmm, may be the fact that printf waits for a long, while 199*25 yields an int.
    True, but the first result had a long variable to begin with to force the promotion to long.

    Also, the incorrect result doesn't look like any kind of endian-swapped or truncated proper result.
    Could this be a compiler bug?
    Devoted my life to programming...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange test results..
    By kwikness in forum C Programming
    Replies: 6
    Last Post: 12-08-2007, 05:47 PM
  2. Strange Results from cout
    By IdioticCreation in forum C++ Programming
    Replies: 8
    Last Post: 11-27-2007, 05:09 AM
  3. Function keys and strange results
    By divineleft in forum Linux Programming
    Replies: 3
    Last Post: 11-12-2006, 06:39 AM
  4. Strange results using dnsapi and windns
    By Niara in forum Networking/Device Communication
    Replies: 3
    Last Post: 08-13-2005, 10:21 AM
  5. mod arithmetic in C++
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 01-10-2002, 12:59 PM