C语言printf的处理方式让人费解,%f输出整型为0,%d和%lld

今天和同学讨论一题:

#include <stdio.h>
int main()
{
	int x = -4;
	unsigned int y = 10;
	int result;
	result = y/x;
	printf("%f",result);
	return 0;
}

刚看到这题,以为只是简单的运算题,说结果就是 10 / - 4 在控制台显示后让人眼睛大跌。
在这里插入图片描述
这是为什么呢,我反复测试,

#include <stdio.h>
int main()
{
	int x = -4;
	unsigned int y = 10;
	int result;
	result = y/x;
	printf("有符号输出:x = %d\n",x);
	printf("无符号输出:x = %u\n",x);
	printf("有符号输出:y = %d\n",y);
	printf("无符号输出:y = %u\n",y);
	printf("结果:resilt = %f",result);
	return 0;
}

在这里插入图片描述
然后就想到数值在计算机中是以补码的形式存储,可以看到x以%d输出时,是原值,以%u输出时是非常接近其表示范围的最大值的,猜想是有符号数和无符号数运算时先将有符号数转换成无符号数,再运算,按照猜想,y / x = 10 / 4294967292 得到的肯定是一个非常小的数,超出了%f的表示范围。
然后就想着变换例子来测试猜想;想着会不会是%f的问题就直接:printf( “ %f ” , 1); 没想到结果还是 0 翻遍论坛原来不止我一个遇见这个问题,有的说是实数和整数在计算机中存储的方式不同,有的说是%f处理数值时是64位,而 int 类型是 32 位所以取不到真实数值。
然后就又换了个例子:

#include<stdio.h>

int main(){
	
	int a=-1;
	unsigned int b = 1;
	int result1 = b/a;
	int result2 = a/b;
	printf("result1 = %d\n",result1);		//负数为分母	
	printf("result1 = %lld\n",result1);		//负数为分母
	printf("result1 = %f\n",result1);		//负数为分母
	printf("result2 = %d\n",result2);		//负数为分子 
	printf("result2 = %lld\n",result2);		//负数为分子 
	printf("result2 = %f\n",result2);		//负数为分子 
	return 0;
} 

在这里插入图片描述
可以看出结果,证实上面的猜想,无符号数是和有符号数运算,是转换成无符号数的补码进行运算,得到的值是非常小的,超出了printf的表示范围。
借着上面的猜想如果把负数放到分子上,那不就可以显示了吗,发现没有,%d显示的是正确结果,%lld输出的却是无符号的最大值,和%u是一样的,而%f还是 0 ,这就又扯出了另一个问题,printf的底层是怎么写的:
在这里插入图片描述
可恶不给看,我猜想是根据%?来识别取值的位数。但是没办法证实,如果有小伙伴知道,请评论告诉我哦。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值