Finding variable overflow`s in C

Discussion in 'Programmer's Corner' started by murkris118, Sep 11, 2013.

  1. murkris118

    Thread Starter New Member

    Sep 11, 2013
    2
    0
    Hi all, as you can see I am a newbie to this forum and would like to start by asking a question that was asked to me in my recent interview.

    1.) How would you find whether a variable is overflowing in C using normal C syntax and features?. For example lets assume there is a int variable and you try to store a long in that, obviously the compiler would not give a compile time error. It will give an output at the cost of sacrificing an overflow. Is there any way to find a variable overflow that you can code inside your program to spit out a user defined error using a printf statement if that happens?.

    2.) How would you store a float number like -12.12345 in a signed long without losing precision? Is this possible because the bit width of the number above is waay less than what can be stored in a signed long or is it impossible to store precision in a signed long?

    Thanks and waiting for your replies guys!!. sorry if I have phrased the question in a way you cant understand. I promise i`ll improve :D..
     
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    1) There's no automatic way to detect an overflow. Best you test the inputs to see of they are in range.

    2) Just arrange the math so the decimal point is shifted, or you may think of it as units. -12.12345 is also 12123450 * 10^-6.
     
  3. murkris118

    Thread Starter New Member

    Sep 11, 2013
    2
    0
    But can the number -1212345*10^-6 be stored in a signed long?. I dont get your solution. can you please elaborate. If I want to store this number in a signed long variable, can u please write down the code block?. I thought only float and double can store precision meaning the decimal portion :confused:...
     
  4. Papabravo

    Expert

    Feb 24, 2006
    10,137
    1,786
    In a strongly typed language like C the statement in bold is untrue. This is not really an overflow situation as much as a type conversion issue. Overflow is taking two signed integers and adding or subtracting them to produce an erroneous result. If you take two positive integers, add them together to produce a negative result, you have overflow.
     
    Last edited: Sep 11, 2013
  5. John P

    AAC Fanatic!

    Oct 14, 2008
    1,632
    224
    Good point there Papabravo--that isn't "overflow" but type conversion, and depending on the warning level, the compiler might give a warning that the program is assigning a long to an int. If that's what you want to do, the right way to do it is with a cast:

    my_int = (int)my_long;

    Microsoft has a lot to say about this stuff (and one thing they emphasize is that it's hard to change types in a totally foolproof manner):
    http://msdn.microsoft.com/en-us/library/hh279667.aspx

    If the issue is floats and longs, I think the interviewer would most like to hear you say that the integer storage gives accurate representation of any number within its range, and the float offers less precision but allows wider range. Obviously, a long can't store anything to the right of the decimal point, but assume that you'd multiply by some amount to make the number an integral. However, then the question becomes "How many decimal places can you do this for, before running out of space in the long? And then, how many decimal places were meaningful in the float anyway?"

    My experience in interviews (on both sides of the table) is that you aren't expecting to hear the exactly correct answer, but a good answer is one that demonstrates that the candidate understands the concepts and can say something intelligent about the topic.
     
  6. mitko89

    Member

    Sep 20, 2012
    123
    19
    1) Don't laugh at this one, please:
    (sizeof(var_int)<sizeof(var_test)) ? (printf("variable exceeds the range"); ) : (printf("variable is in range"); );

    2) I think the responses given so far are by far better than any I can think of, at least for now.

    edit: for the 1st question I assumed it's about assigning a value to int variable
     
    Last edited: Sep 11, 2013
  7. Papabravo

    Expert

    Feb 24, 2006
    10,137
    1,786
    In C there are a number of tests you can do on the operands and the results to detect overflow. In the case of 8-bit signed integers in the range [-128,...,127] you can test bit 7 of each operand and bit 7 of the result to detect overflow.
    Code ( (Unknown Language)):
    1.  
    2. unsigned short int A, B, R, V
    3. ...
    4. // do the operation
    5. R = A - B ;
    6.  
    7. // test for overflow
    8. A7 = A & 0x80 ;
    9. B7 = B & 0x80 ;
    10. R7 = R & 0x80 ;
    11.  
    12. V = (A7 & ~B7 & ~R7) | (~A7 & B7 & R7) ;
    13. if (V == 1 ) goto overflow ;
    14. else goto no_overflow ;
    15.  
    The code implements the following logic:
    if (A is positive) AND (B is negative) AND (R is negative) then overflow
    OR
    if (A is negative) AND (B is positive) AND (R is positive) then overflow
    otherwise no overflow
     
  8. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    You missed a zero when you missed the point.

    12123450 (see that last zero) CAN be stored and manipulated as an integer value.

    Say it represents a voltage. Your code treats it with an implied unit of [microvolt].
     
  9. MrChips

    Moderator

    Oct 2, 2009
    12,432
    3,360
    Precisely! This is called fixed point arithmetic.

    -12.12345V becomes -12123450μV.

    You just have to remember that all your values are scaled by a known factor.
     
  10. WBahn

    Moderator

    Mar 31, 2012
    17,720
    4,788
    You need to clarify what you mean by "variable exceed the range". Are you talking about the specific value presently stored in a variable, or the overall question of whether you can store any and all possible values of one type of variable in another?

    sizeof() is a macro that is evaluated to a number by the preprocessor before the code goes to the compiler. Note also that it only returns the number of bytes of storage used for that data type and is completely silent on the range of values that it can represent. For instance, sizeof(int) and sizeof(unsigned int) will return exactly the same value (typically 4 on most modern compilers) yet there are values in each type that cannot be stored in the other type.
     
  11. mitko89

    Member

    Sep 20, 2012
    123
    19
    I wrote the answer while thinking of this one. But forgot about that sizeof() is evaluated before compilation. And didn't really though about the unsigned and signed value limitations. I have to be more aware of these in future.
    Well, just tried to give an idea...
     
  12. WBahn

    Moderator

    Mar 31, 2012
    17,720
    4,788
    In general, you need to perform tests before storing the value.

    If you have

    int a;
    long b;

    Then utilize the predefined constants in limits.h (IIRC). I don't remember the exact names, but now that you know about them you can look them up. There is one called or INT_MAX (or something like that) and also INT_MIN.

    So can can go

    if ((b <= INT_MAX) && (b >= INT_MIN))
    // Okay
    else
    // Not okay

    Similarly, you can check if operations will result in overflow

    int a,b,c;

    // Check that c = a + b won't overflow

    if (((b>0)&&((INT_MAX-b)<a))||((b<0)&&((INT_MIN-b)>a))
    // Overflow will happen

    Of course, if you know certain constraints beforehand, such as knowing that 'a' will always be positive, you can trim this down.
     
    mitko89 likes this.
  13. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
Loading...