Linux下C类型变量转换问题

iron_li 2013-12-20 02:12:11
写了一个代码,输出结果和预想不符,代码如下:
#include <stdio.h>

int main(void)
{
unsigned int a = 200, b = 1, c = 0;
double d = 0;
c = (a - b)/10.0;
d = (a - b)/10.0;
double myvar = (a - b)/10.0;
printf("c: %f, d: %lf, myvar: %lf\n", c, d, myvar); //myvar的结果不对
return 0;
}

输出结果:c: 19.900000, d: 19.900000, myvar: 0.000000
为什么最后一个为0.000000啊?
...全文
165 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
iron_li 2013-12-20
  • 打赏
  • 举报
回复
引用 10 楼 changhonghuan 的回复:
[quote=引用 2 楼 Meteor_Code 的回复:] 栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
在printf函数的栈中有 c(unsigned int)、d(double)、myvar(double)共20个字节 格式符%f、%lf、%lf分别占8、8、4个字节 实际结果并不是上面所谓的c: 19.900000, d: 19.900000, myvar: 0.000000 我在gcc下的结果 c:190359804756585290800225004697592000611708095954661757616245032484253127904326938471236694422145581236194734089529829625833353930779766597086044360372489629850129256972431021890192015360.000000,d:190359837277366669655647163314481214536991132162652612850933061001090513015105157377943616157470427089203491673116049516810865697391842691589967491289407861429180783102463018374470303744.000000, myvar: -0.139144 [/quote] 我也是红帽6 x86_64下GCC编译后的执行输出结果,为什么和你的差别那么大,难道GCC编译时有参数可以设置打印精度吗?
iron_li 2013-12-20
  • 打赏
  • 举报
回复
c: 19.900000, d: 19.900000, myvar: 0.000000 以上是我在红帽6 x86_64下的输出结果。
引用 13 楼 Meteor_Code 的回复:
[quote=引用 12 楼 changhonghuan 的回复:] [quote=引用 11 楼 Meteor_Code 的回复:] [quote=引用 10 楼 changhonghuan 的回复:] [quote=引用 2 楼 Meteor_Code 的回复:] 栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
在printf函数的栈中有 c(unsigned int)、d(double)、myvar(double)共20个字节 格式符%f、%lf、%lf分别占8、8、4个字节 实际结果并不是上面所谓的c: 19.900000, d: 19.900000, myvar: 0.000000 我在gcc下的结果 c:190359804756585290800225004697592000611708095954661757616245032484253127904326938471236694422145581236194734089529829625833353930779766597086044360372489629850129256972431021890192015360.000000,d:190359837277366669655647163314481214536991132162652612850933061001090513015105157377943616157470427089203491673116049516810865697391842691589967491289407861429180783102463018374470303744.000000, myvar: -0.139144 [/quote] gcc还区分%f和%lf吗??vs下好像是不区分的,float入栈好像都会被转化成8字节的double[/quote] 对啊,没有区分,所以才是格式符对应的输出字节才是8、8、4[/quote] 格式符%f、%lf、%lf分别占8、8、4个字节??????[/quote] 格式符%f、%lf、%lf应该还是占8、8、8个字节,只不过最后一个读到的后四个字节是不属于我的20个字节范围内的吧?
Meteor_Code 2013-12-20
  • 打赏
  • 举报
回复
引用 12 楼 changhonghuan 的回复:
[quote=引用 11 楼 Meteor_Code 的回复:] [quote=引用 10 楼 changhonghuan 的回复:] [quote=引用 2 楼 Meteor_Code 的回复:] 栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
在printf函数的栈中有 c(unsigned int)、d(double)、myvar(double)共20个字节 格式符%f、%lf、%lf分别占8、8、4个字节 实际结果并不是上面所谓的c: 19.900000, d: 19.900000, myvar: 0.000000 我在gcc下的结果 c:190359804756585290800225004697592000611708095954661757616245032484253127904326938471236694422145581236194734089529829625833353930779766597086044360372489629850129256972431021890192015360.000000,d:190359837277366669655647163314481214536991132162652612850933061001090513015105157377943616157470427089203491673116049516810865697391842691589967491289407861429180783102463018374470303744.000000, myvar: -0.139144 [/quote] gcc还区分%f和%lf吗??vs下好像是不区分的,float入栈好像都会被转化成8字节的double[/quote] 对啊,没有区分,所以才是格式符对应的输出字节才是8、8、4[/quote] 格式符%f、%lf、%lf分别占8、8、4个字节??????
FireXun 2013-12-20
  • 打赏
  • 举报
回复
引用 11 楼 Meteor_Code 的回复:
[quote=引用 10 楼 changhonghuan 的回复:] [quote=引用 2 楼 Meteor_Code 的回复:] 栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
在printf函数的栈中有 c(unsigned int)、d(double)、myvar(double)共20个字节 格式符%f、%lf、%lf分别占8、8、4个字节 实际结果并不是上面所谓的c: 19.900000, d: 19.900000, myvar: 0.000000 我在gcc下的结果 c:190359804756585290800225004697592000611708095954661757616245032484253127904326938471236694422145581236194734089529829625833353930779766597086044360372489629850129256972431021890192015360.000000,d:190359837277366669655647163314481214536991132162652612850933061001090513015105157377943616157470427089203491673116049516810865697391842691589967491289407861429180783102463018374470303744.000000, myvar: -0.139144 [/quote] gcc还区分%f和%lf吗??vs下好像是不区分的,float入栈好像都会被转化成8字节的double[/quote] 对啊,没有区分,所以才是格式符对应的输出字节才是8、8、4
Meteor_Code 2013-12-20
  • 打赏
  • 举报
回复
引用 10 楼 changhonghuan 的回复:
[quote=引用 2 楼 Meteor_Code 的回复:] 栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
在printf函数的栈中有 c(unsigned int)、d(double)、myvar(double)共20个字节 格式符%f、%lf、%lf分别占8、8、4个字节 实际结果并不是上面所谓的c: 19.900000, d: 19.900000, myvar: 0.000000 我在gcc下的结果 c:190359804756585290800225004697592000611708095954661757616245032484253127904326938471236694422145581236194734089529829625833353930779766597086044360372489629850129256972431021890192015360.000000,d:190359837277366669655647163314481214536991132162652612850933061001090513015105157377943616157470427089203491673116049516810865697391842691589967491289407861429180783102463018374470303744.000000, myvar: -0.139144 [/quote] gcc还区分%f和%lf吗??vs下好像是不区分的,float入栈好像都会被转化成8字节的double
FireXun 2013-12-20
  • 打赏
  • 举报
回复
引用 2 楼 Meteor_Code 的回复:
栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
在printf函数的栈中有 c(unsigned int)、d(double)、myvar(double)共20个字节 格式符%f、%lf、%lf分别占8、8、4个字节 实际结果并不是上面所谓的c: 19.900000, d: 19.900000, myvar: 0.000000 我在gcc下的结果 c:190359804756585290800225004697592000611708095954661757616245032484253127904326938471236694422145581236194734089529829625833353930779766597086044360372489629850129256972431021890192015360.000000,d:190359837277366669655647163314481214536991132162652612850933061001090513015105157377943616157470427089203491673116049516810865697391842691589967491289407861429180783102463018374470303744.000000, myvar: -0.139144
Meteor_Code 2013-12-20
  • 打赏
  • 举报
回复
引用 8 楼 lizhenneng 的回复:
各种大牛啊,谢谢。二楼的解释很清楚。
更正以下,其实是我看错了 d是个double, 你第1个%f读到的是c和d低4字节拼成的double 第2个%lf读到的是d高4字节和myvar的低4字节拼成的double 第3个%lf读到的是myvar高4字节和栈中的"残余"拼成的double 所以胡乱了
iron_li 2013-12-20
  • 打赏
  • 举报
回复
各种大牛啊,谢谢。二楼的解释很清楚。
赵4老师 2013-12-20
  • 打赏
  • 举报
回复
printf("%按熊猫的格式输出\n",CSDN的lizhenneng); lizhenneng觉得合理的输出应该是……
云斜月 2013-12-20
  • 打赏
  • 举报
回复
应该涉及到类型之间的转换和精度问题,你找下这方面的资料
lin5161678 2013-12-20
  • 打赏
  • 举报
回复
第一个参数和格式控制字符串不一致 后面数据全部错位
derekrose 2013-12-20
  • 打赏
  • 举报
回复
什么编译器啊 这么奇葩
大奶兔白糖 2013-12-20
  • 打赏
  • 举报
回复
d是double类型的
Meteor_Code 2013-12-20
  • 打赏
  • 举报
回复
栈被你弄错了, printf 看到第一个 %f是,知道你后面有个8字节的double,所以读出一个double,可实际上这个double是你入栈的两个unsigned int c,d构成的,至于c,d为什么能拼成19.900000,你就自己百度double的结构吧 然后看到第2个%lf,知道你后面是一个double,注意,printf 把你的unsigned int c,d看成一个double,所以你第2个%lf实际上读的是myvar这个double,所以是19.900000 第3个%lf,实际上栈中已经没有数值了,读到的东西只不过是栈中的残余内容,恰巧和0.000000差不多,,,
大奶兔白糖 2013-12-20
  • 打赏
  • 举报
回复
c不是整形吗?怎么会是19.9?

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧