使用%d或%i进行类型转换后进行打印会产生意外的输出 [英] Printing after typecasting with %d or %i gives unexpected outputs

查看:73
本文介绍了使用%d或%i进行类型转换后进行打印会产生意外的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在舍入一些值,然后打印它们。当我使用%f选项时,它们可以正确打印,但是使用%d或%i选项(即使在将舍入后的值转换为int之后)也会给出奇怪的输出,而我无法弄清楚其原因。



任何帮助都非常感谢!



当我使用%f时:

  i = 0; 

while(i< n_shapes)
{
ll_x [i] =(int)round((ll_x [i]-min_x)/ pitch_x);
ll_y [i] =(int)round((ll_y [i]-min_y)/ pitch_y);
ur_x [i] =(int)round((ur_x [i]-min_x)/ pitch_x);
ur_y [i] =(int)round((ur_y [i]-min_y)/ pitch_y);
printf(%f,%f,%f,%f\n,ll_x [i],ll_y [i],ur_x [i],ur_y [i]);
i ++;
}

输出:

  115.000000,94.000000,115.000000,101.000000 
116.000000,51.000000,117.000000,58.000000
116.000000,60.000000,117.000000,67.000000
116.000000,69.000000,117.000000,75.000000
116.000000,77.000000,117.000000,84.000000
116.000000,86.000000,117.000000,93.000000
116.000000,94.000000,117.000000,101.000000

现在,带有%d(或%i):

  i = 0 ; 

while(i< n_shapes)
{
ll_x [i] =(int)round((ll_x [i]-min_x)/ pitch_x);
ll_y [i] =(int)round((ll_y [i]-min_y)/ pitch_y);
ur_x [i] =(int)round((ur_x [i]-min_x)/ pitch_x);
ur_y [i] =(int)round((ur_y [i]-min_y)/ pitch_y);
printf(%d,%d,%d,%d\n,ll_x [i],ll_y [i],ur_x [i],ur_y [i]);
i ++;
}

输出:

  1079590912,0,6,-1 
1078788096,0,5,-1
1079033856,0,6,-1
1079164928,0, 6,-1
1079312384,0,6,-1
1079459840,0,6,-1
1079590912,0,6,-1

谢谢!



编辑:是的,我知道在printf给我正确的输出。我很好奇我当时没有得到的价值观。当我使用%d而不在printf内部进行转换时,我的输出是什么意思?

解决方案

这是未定义的行为。您需要使用正确的类型说明符。



printf 无法验证传递给它的参数类型用于打印的匹配其相应的格式说明符。编译器在传递这些参数之前会执行特定于类型的转换,因此 printf 期望如果每个%f 找到一个 double float 也将转换为 double )和对于每个%d ,它将找到一个 int 。您的代码为该%d 说明符传递了一个 double 转换后的值,这会导致未定义的行为。



请注意,将 float double 表达式强制转换为 int 分配给 float double 变量之前,不会更改号码。它所做的只是截断小数部分。表示保持不变。换句话说,如果您这样做

  double x = 12.345; 
double y =(int)x;



<$ p $相同p> double x = 12.345;
double y =(double)((int)x);

因为在这种情况下,编译器知道变量 y ,并为您插入缺少的演员。


I am rounding off some values and then printing them. When I use %f option, they are printed correctly, but using the %d or %i option (even after casting the rounded values to int) is giving a weird output, and I am not able to figure the why of it out.

Any help is much appreciated!

When I use %f:

i = 0;

while(i < n_shapes)
{
    ll_x[i] = (int)round((ll_x[i] - min_x)/pitch_x);
    ll_y[i] = (int)round((ll_y[i] - min_y)/pitch_y);
    ur_x[i] = (int)round((ur_x[i] - min_x)/pitch_x);
    ur_y[i] = (int)round((ur_y[i] - min_y)/pitch_y);
    printf("%f,%f,%f,%f\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
    i++;
}

Output:

115.000000,94.000000,115.000000,101.000000
116.000000,51.000000,117.000000,58.000000
116.000000,60.000000,117.000000,67.000000
116.000000,69.000000,117.000000,75.000000
116.000000,77.000000,117.000000,84.000000
116.000000,86.000000,117.000000,93.000000
116.000000,94.000000,117.000000,101.000000

Now, with %d (or %i):

i = 0;

while(i < n_shapes)
{
    ll_x[i] = (int)round((ll_x[i] - min_x)/pitch_x);
    ll_y[i] = (int)round((ll_y[i] - min_y)/pitch_y);
    ur_x[i] = (int)round((ur_x[i] - min_x)/pitch_x);
    ur_y[i] = (int)round((ur_y[i] - min_y)/pitch_y);
    printf("%d,%d,%d,%d\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
    i++;
}

Output:

1079590912,0,6,-1
1078788096,0,5,-1
1079033856,0,6,-1
1079164928,0,6,-1
1079312384,0,6,-1
1079459840,0,6,-1
1079590912,0,6,-1

Thank you!

Edit: Yes, I realize that using (int) in the printf gives me the right output. I was curious about the values I got when I didn't do so. What does my output when I use %d without casting inside the printf mean?

解决方案

This is undefined behavior. You need to use the correct type specifier.

printf cannot verify that the types of parameters that you pass to it for printing match their corresponding format specifiers. The compiler performs type-specific conversions before passing these parameters, so printf expects that for each %f if would find a double (float gets converted to double as well) and for each %d it would find an int. Your code passes a double-converted value for that %d specifier, which causes undefined behavior.

Note that casting a float or a double expression to int before assigning to a float or double variable does not change the representation of the number. All it does is truncating the fractional part. The representation remains the same. In other words, if you do

double x = 12.345;
double y = (int)x;

it is the same as

double x = 12.345;
double y = (double)((int)x);

because in this case the compiler knows the type of variable y, and inserts the missing cast for you.

这篇关于使用%d或%i进行类型转换后进行打印会产生意外的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆