i=i+1 是未定义的行为吗?
Is i=i+1 an undefined behaviour?
我正在使用代码块,它为其他编译器提供了不同的输出,我找不到 it.What 这个程序中未定义行为的解决方案,是否有任何解决方案可以避免它?
这是在只有 3 和 4 的数字系统中打印第 n 个数字的代码。
#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 的数字的输出比实际应该的少 1。例如。如果 n=7,output=332 应该是 333.
编辑:提供带大括号的完整代码。
浮点数似乎被截断了。
您正在使用具有签名
的函数 pow()
double pow(double x, double y);
和计算作为 int。 Rounding/truncation 个错误?
此代码中没有未定义的行为。 i=i+1;
是明确定义的行为,不要与给出未定义行为的 i=i++;
混淆。
这里唯一可能导致不同输出的是 floating point inaccuracy。
尝试 value += 4 * (int)nearbyint(pow(10,i));
看看是否有任何不同。
这听起来像是一个编译器错误。
您将结果计算为 value+=3*pow(10,i);
但这实际上转化为 value+= (int)(3*pow(10,i));
这里有两件事中的一件可能是错误的:
- pow(10,0)!=1.0
- 转换为 int 错误地截断了结果。
要轻松调试它,只需尝试打印部分结果并查看问题所在。
这里的问题很可能是这个特定平台上的 pow
函数通过取参数的对数(可能是自然对数;可能是对数基数 2)乘以指数来执行计算,然后然后将第一个对数的底数提高到该乘积的幂。对无限精度数字执行这样的操作会产生数学上正确的结果,就像对扩展精度数字执行操作和 returning double
结果一样。我的猜测是,此实现中使用的 pow
函数可能是为一个平台编写的,该平台可以使用扩展精度数字执行中间计算,因此 return 可以更正双精度值,但它在缺少扩展精度类型的平台上 运行。因此,pow(10,3)
可能会 return 生成类似 999.9999999997 的内容,并将其强制转换为 int
会得到 999 而不是 1000。
如果您试图获得整数类型的结果,则确实没有理由将幂计算为浮点值。与其在循环中计算 10^i,不如让一个变量初始化为 1 并在每次循环中乘以 10 会更好。
我正在使用代码块,它为其他编译器提供了不同的输出,我找不到 it.What 这个程序中未定义行为的解决方案,是否有任何解决方案可以避免它?
这是在只有 3 和 4 的数字系统中打印第 n 个数字的代码。
#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 的数字的输出比实际应该的少 1。例如。如果 n=7,output=332 应该是 333.
编辑:提供带大括号的完整代码。
浮点数似乎被截断了。
您正在使用具有签名
的函数 pow()double pow(double x, double y);
和计算作为 int。 Rounding/truncation 个错误?
此代码中没有未定义的行为。 i=i+1;
是明确定义的行为,不要与给出未定义行为的 i=i++;
混淆。
这里唯一可能导致不同输出的是 floating point inaccuracy。
尝试 value += 4 * (int)nearbyint(pow(10,i));
看看是否有任何不同。
这听起来像是一个编译器错误。
您将结果计算为 value+=3*pow(10,i);
但这实际上转化为 value+= (int)(3*pow(10,i));
这里有两件事中的一件可能是错误的:
- pow(10,0)!=1.0
- 转换为 int 错误地截断了结果。
要轻松调试它,只需尝试打印部分结果并查看问题所在。
这里的问题很可能是这个特定平台上的 pow
函数通过取参数的对数(可能是自然对数;可能是对数基数 2)乘以指数来执行计算,然后然后将第一个对数的底数提高到该乘积的幂。对无限精度数字执行这样的操作会产生数学上正确的结果,就像对扩展精度数字执行操作和 returning double
结果一样。我的猜测是,此实现中使用的 pow
函数可能是为一个平台编写的,该平台可以使用扩展精度数字执行中间计算,因此 return 可以更正双精度值,但它在缺少扩展精度类型的平台上 运行。因此,pow(10,3)
可能会 return 生成类似 999.9999999997 的内容,并将其强制转换为 int
会得到 999 而不是 1000。
如果您试图获得整数类型的结果,则确实没有理由将幂计算为浮点值。与其在循环中计算 10^i,不如让一个变量初始化为 1 并在每次循环中乘以 10 会更好。