i = i + 1是未定义的行为吗?

时间:2015-06-15 11:29:25

标签: c increment undefined-behavior

我正在使用代码块,并且它给其他编译器提供了不同的输出,我找不到它的解决方案。这个程序中的未定义行为是什么,是否有任何解决方案可以避免它?

这是在数字系统中打印第n个数字的代码,只有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);                                                                          
}

对于高达6的数字,它可以正常工作。大于6的数字的输出比实际应该的数字少一个。例如。如果n = 7,则输出= 332,其中应为333。

编辑:提供带括号的完整代码。

5 个答案:

答案 0 :(得分:3)

你正在使用功能pow(),它具有签名

double pow(double x, double y);

并计算为int。舍入/截断错误?

答案 1 :(得分:2)

此代码中没有未定义的行为。 i=i+1;是明确定义的行为,不要与提出未定义行为的i=i++;混淆。

唯一可能导致不同输出的因素是floating point inaccuracy

尝试value += 4 * (int)nearbyint(pow(10,i));,看看它是否有所作为。

答案 2 :(得分:0)

似乎浮点被截断。

答案 3 :(得分:0)

这听起来像编译错误。 您将结果计算为value+=3*pow(10,i);但实际上转换为值+ =(int)(3 * pow(10,i));

这里可能有两件事情之一:

  1. POW(10,0)!= 1.0
  2. cast to int正在错误地截断结果。
  3. 要轻松调试,只需尝试打印部分结果并查看问题所在。

答案 4 :(得分:0)

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.