Sum of positive values in an array gives negative result in a c program

后端 未结 4 1555
渐次进展
渐次进展 2021-01-26 10:16

I have a problem that is, when I sum the values of an array (that are all positive, I verified by printing the values of the array), I end up with a negative value. My code for

相关标签:
4条回答
  • 2021-01-26 10:21

    This smells like an overflow issue; you might want to add a check against that like

    for (k = 0; k < SIMUL && (INT_MAX - summcp > mcp[k]); k++ )
    {
      sumcp += mcp[k];
    }
    
    if (k < SIMUL)
    {
      // sum of all mcp values is larger than what an int can represent
    }
    else
    {
      // use summcp
    }
    

    If you are running into overflow issues, you might want to use a wider type for summcp like long or long long.

    EDIT

    The problem is that the behavior of signed integer overflow is not well-defined; you'll get a different result for INT_MAX + 1 based on whether your platform uses one's complement, two's complement, sign magnitude, or some other representation for signed integers.

    Like I said in my comment below, if mcp can contain negative values, you should add a check for underflow as well.

    Regardless of the type you use (int, long, long long), you should keep the over- and underflow checks.

    If mcp only ever contains non-negative values, then consider using an unsigned type for your sum. The advantage of this is that the behavior of unsigned integer overflow is well-defined, and the result will be the sum of all elements of mcp modulo UINT_MAX (or ULONG_MAX, or ULLONG_MAX, etc.).

    0 讨论(0)
  • 2021-01-26 10:26

    I think your final output is going out of range. For this you will have to declare summcp as long long int

    long long int summcp = 0;
    for (k = 0; k < SIMUL; k++)
    {
        summcp += mcp[k];
    }
    printf("summcp: %lld.\n", summcp);
    

    int variable throws garbage value if its range is exceeded.

    0 讨论(0)
  • 2021-01-26 10:29

    You are invoking undefined behaviour.

    As integer variables can only hold a limited range of values, going beyond this range is undefined by the standard. Basically anything can happen. In your (and the most common) case, it simply wraps around its binary representation. As this is used for negative values, you will read this as such.

    To circomvent this, use a type for summcp which can hold all possible values. An alternative would be to check if the next addition will overflow by:

    if ( summcp >= INT_MAX - mcp[k] ) {
        // handle positive overflow
    }
    

    Note that the above only works for mcp[k] >= 0 and positive overflow. The other 3 cases have to be handled differently. It is in general best, faster and much easier to use a large enough type for the sum and test lateron for overflow, if required.

    Do not feel tempted to add and test the result!. As integer overflow is undefined behaviour, this will not work for all architectures.

    0 讨论(0)
  • 2021-01-26 10:36

    Declare variable summcp like

    long long int summcp = 0;
    
    0 讨论(0)
提交回复
热议问题