Is i=i+1 an undefined behaviour?

194 views Asked by At

I'm using codeblocks and it is giving a different output to other compilers and I can't find a solution to it.What's the undefined behaviour in this program and is there any solution to avoid it?

This is the code to print the nth number in a number system with only 3 & 4.

#include<stdio.h>                                                              
#include<math.h>                                                               
int main(void)                                                                 
{                                                                              
    int n,i,value;                                                             
    scanf("%d",&n);                                                            
    value=i=0;                                                                 
    while(n>0)                                                                 
    {                                                                          
        if((n%2)==0)                                                           
        {                                                                      
            value+=4*pow(10,i);                                                
        }                                                                      
        else                                                                   
        {                                                                      
            value+=3*pow(10,i);                                                
        }                                                                      
        n=(n-1)/2;                                                             
        i=i+1;                                                                 
    }
printf("\nThe number is : %d",value);                                                                          
}

It works fine for numbers upto 6..And the output for numbers greater than 6 is one less than what it actually should be. E.g. if n=7,output=332 where it should be 333.

EDIT : Provided the full code with braces.

5

There are 5 answers

0
Lundin On BEST ANSWER

There is no undefined behavior in this code. i=i+1; is well-defined behavior, not to be confused with i=i++; which gives undefined behavior.

The only thing that could cause different outputs here would be floating point inaccuracy.

Try value += 4 * (int)nearbyint(pow(10,i)); and see if it makes any difference.

0
alagner On

Seems that floating point gets truncated.

0
Michel Billaud On

you're using the function pow(), which has the signature

double pow(double x, double y);

and calculations as int. Rounding/truncation errors ?

0
supercat On

The problem here is most likely that the pow function on this particular platform performs its computations by taking the log of the argument (perhaps natural log; perhaps log base 2), multiplying by the exponent, and then raising the base of the first logarithm to the power of that product. Performing such an operation with infinite-precision numbers would yield a mathematically-correct result, as would performing the operation on extended-precision numbers and returning a double result. My guess would be that the pow function used on this implementation may have been written for a platform which could perform the intermediate computations using extended-precision numbers, and which would consequently return correct double-precision values, but it is being run on a platform which lacks an extended-precision type. As a consequence of this, pow(10,3) may be returning something like 999.9999999997, and coercing that to int yields 999 rather than 1000.

If you're trying to get an integer-type result, there's really no reason to compute the power as a floating-point value. Rather than computing 10^i within the loop, it would be better to have a variable that's initialized to 1 and gets multiplied by 10 each time through the loop.

0
Pandrei On

It sounds like a compiler bug. You are computing the result as value+=3*pow(10,i); but what this actually translates to is value+= (int)(3*pow(10,i));

One of two things might be wrong here:

  1. pow(10,0)!=1.0
  2. cast to int is truncating the result incorrectly.

To debug it easily just try printing the partial results and see there the problem is.