[问题] printf 格式不同问题(修正)

楼主: hpyhacking (骇人听闻)   2017-10-27 02:29:16
开发平台(Platform): (Ex: Win10, Linux, ...)
win 10 用cygwin64
64位元
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
GCC
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
no
问题(Question):
简单的printf问题
int a = 10;
printf( "%f\n", a );
float w = 35.14;
printf( "%w d\n", w );
喂入的资料(Input):
没有
预期的正确结果(Expected Output):
预期第一个printf输出的是10.0
当然结果大家知道是0
想请问为什么这个型态错误印出的是0 ?
原本想说都是占4bytes应该会误打误撞可以显示好
爬到英文说跟什么IEEE有关?英文看不是很懂....
再来既然格式都一样错误
为什么第二个printf有印出东西但是是乱数,这个数是其他内存空间里的数字吗?
错误结果(Wrong Output):
0 ( undefined? )
1073741824 ( 乱数 )
程式码(Code):(请善用置底文网页, 记得排版)
补充说明(Supplement):
作者: LPH66 (-6.2598534e+18f)   2017-10-27 02:34:00
这问题会牵涉到不少这些 C 语言功能的实作细节要完整回答会很长一串, 但一般写程式不需要考虑这些细节
作者: kingofsdtw (不能閒下來!!)   2017-10-27 02:35:00
google吧 :D
作者: Schottky (顺风相送)   2017-10-27 02:41:00
我觉得不好,我觉得这样写程式很危险,把 -Wall 打开吧
楼主: hpyhacking (骇人听闻)   2017-10-27 02:44:00
这是故意的
作者: a58524andy (a58524andy)   2017-10-27 06:00:00
先读计概
作者: peterwu4 (notd)   2017-10-27 07:42:00
可以查一下float和int储存格式的差异~ 啊,你已经查了XD找中文的网页说明来看~
作者: vm0 (....)   2017-10-27 10:17:00
我实际在linux上用gcc跑,printf("%d\n",w)会是35,跟印象中一样,在宣告时就会自动省略小数,请教是为什么呢?
作者: nh60211as   2017-10-27 10:22:00
他要打double w = 35.14打错了吧
作者: vm0 (....)   2017-10-27 10:41:00
原来如此,看前几楼回的还以为我哪里搞错了,谢谢
作者: nh60211as   2017-10-27 10:56:00
我也不确定,照他的错误结果输入应该是浮点数才对
作者: MOONRAKER (㊣牛鹤鳗毛人)   2017-10-27 11:08:00
printf不依照格式字串检查变量格式。有错误结果自负。
楼主: hpyhacking (骇人听闻)   2017-10-27 12:07:00
先谢谢大家一声,还有我现在就是在读计概QQ不好意思有打错的!!!
作者: Schottky (顺风相送)   2017-10-27 13:38:00
假如 printf 期望的 size 和变量 size 不一样会出大事
作者: ersfw4418 (隐身术)   2017-10-27 16:47:00
IEEE754
作者: yvb   2017-10-27 20:42:00
若是要 "正确的" 把 double "误" 当做 int 来印, 应该写做printf("%d\n", *(int *)&w); 结果 35.14 会是 -2061584302而原 PO 的 printf("%d\n", w); 在 Linux 系统开了 ASLR 时,甚至每次显示结果都不同, 真的像是乱数一般. 显然是 va_list这个黑盒子中不知发生了什么事.
作者: akasan (KITO)   2017-10-27 20:48:00
ABI
作者: AstralBrain   2017-10-27 21:30:00
以 amd64 来说, 浮点数 w 会进 xmm0 register然后 printf 从没使用的 rdi 读一个整数, 所以是什么值都有可能
作者: PkmX (阿猫)   2017-10-28 15:45:00
楼上rdi应该是format string 所以下一个参数是rsi
作者: AstralBrain   2017-10-29 06:08:00
啊对... 忘了有 format string
作者: LPH66 (-6.2598534e+18f)   2017-10-29 09:13:00
这里还要考虑可变参数, 我其实不太确定 amd64 的可变参数会不会用到浮点数暂存器...我所知的可变参数实作几乎都是全部推堆叠噢, 找到资料了, 即使是可变参数 amd64 一样会用暂存器那用了多少 xmm 暂存器传浮点数会以 al 传进去所以就是上面 Astral 讲的那个样子
作者: yvb   2017-10-30 00:46:00
其实我前面只是要指出, 原PO 的问题, 在 X86-64 的环境下,并非单纯是 IEEE754 的问题, 照规则算出 "乱数" 会不符合;当然, 若是在 i386 (32-bit) 的环境, 应该就会回归单纯了.另外, 上面 regs 的推论, 会让人觉得在瞎子摸象, 可参考(1) http://goo.gl/yP27aR 及 (2) http://goo.gl/WPLhd9此外, 依据 (1) 及其后 List 的 X86-64 段落, 我的测试使用Linux => System V AMD64 ABI, 但原PO 则为 Win10 cygwin64,不知是会采用 SysV 还是 M$ X64 calling convention ?有关 regs 的相关推论, 不知是否依旧完全符合?
楼主: hpyhacking (骇人听闻)   2017-11-10 17:53:00
今天期中考完我再来研究一下

Links booklink

Contact Us: admin [ a t ] ucptt.com