标题:以下两份代码为何有这差别?
只看楼主
hffjhhh
Rank: 1
等 级:新手上路
帖 子:127
专家分:7
注 册:2019-4-10
结帖率:90.38%
已结贴  问题点数:20 回复次数:15 
以下两份代码为何有这差别?
第一份代码的输出结果为3.300000,代码如下:
程序代码:
#include"stdio.h"
int main(void){
    double num;
    num=3.3;
    printf("%lf",num);
    return 0;
}

第二份代码的输出结果为0.000000,代码如下:
程序代码:
#include"stdio.h"
int main(void){
    long double num;
    num=3.3;
    printf("%lf",num);
    return 0;
}

为何第二份代码加了个long,就产生这样的输出结果?
搜索更多相关主题的帖子: printf num 代码 输出 结果 
2020-06-11 23:12
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
得分:5 
程序代码:
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%lf\n", 0x400a660000000000);
}


有个截断问题,手工只能算到这种程度了(给的3.3实在有点缺德)……

注:突然发现个重大问题,程序在龙芯3A2000下可以得到正确结果,但在intel i56400 gcc-6.3.0 deepin-15.11平台上结果全是0

[此贴子已经被作者于2020-6-12 08:24编辑过]


梦想拥有一台龙芯3A-4000
2020-06-12 02:30
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:5 
long double 用 "%Lf",大写的L
2020-06-12 07:19
lin5161678
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:45
帖 子:1136
专家分:3729
注 册:2011-12-3
得分:5 
格式和实参类型不匹配是未定义行为
这是出现这个情况的标准依据
再具体实现中
printf 根据格式化字符判断实参类型 进而决定读取多少个字符进行类型解析
这里假如 double 类型8字节 long double 类型12字节
那么 实参入栈long double 至少12个字节 printf调用到时候 按照%f处理只读取8个字节
GG

而两个类型的大小在不同编译环境中是不确定的
有的编译环境 long double 和 double 一样大
所以你有时候能看到 输出和double一样的结果
这不奇怪 这只是作死

https://zh.
2020-06-12 09:21
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
得分:0 

1. 已实验完成long(包括long long)、double类型;long double还没整出来。起码可以肯定的是,gcc优先用寄存器传递参数(有时间再慢慢看是传递的地址还是内容),寄存器用完后,才会选择栈(估计windows也差不多)。

2. 如果前述double编码正确,那么long double类型的编码形式应该可以倒推出来;因为可以先用sizeof(long double)知道编码字节数,比如12或16字节(如果写书,用未定义应该也算正确)。

梦想拥有一台龙芯3A-4000
2020-06-12 13:05
hffjhhh
Rank: 1
等 级:新手上路
帖 子:127
专家分:7
注 册:2019-4-10
得分:0 
以下是引用rjsp在2020-6-12 07:19:19的发言:

long double 用 "%Lf",大写的L

即使改成了Lf也一样还是打印0.000000.
程序代码:
#include"stdio.h"
int main(void){
    long double num;
    num=3.3;
    printf("%Lf",num);
    return 0;
}
2020-06-12 13:19
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
得分:0 
%llf再试一下

梦想拥有一台龙芯3A-4000
2020-06-12 14:02
hffjhhh
Rank: 1
等 级:新手上路
帖 子:127
专家分:7
注 册:2019-4-10
得分:0 
以下是引用ditg在2020-6-12 14:02:39的发言:

%llf再试一下

试了,还是不行。还是打印0.000000
2020-06-12 14:37
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
得分:0 
http://www.
(网站已测试,关于数据转换的)

也不知是intel还是gcc默认不是IEEE 754浮点编码标准;long double使用浮点运算单元。


(以后谁要再拿long double类型说事,小心我拿烟头烫他!)

[此贴子已经被作者于2020-6-12 18:56编辑过]


梦想拥有一台龙芯3A-4000
2020-06-12 18:40
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
得分:0 
回复 8楼 hffjhhh
如果是我会像下面这样:

先sizeof(long double),看是否支持某种类型;如果=16(其它值暂时没见过);再执行汇编浮点指令finit或fninit,接着随便执行一条你确实知道返回值含义的浮点指令,判断有没有协处理器(我试了一下,用户空间好像也能执行);正常后试着看一下程序的返回值。如果一切正常,我认为就是编译器后端解码的问题

梦想拥有一台龙芯3A-4000
2020-06-12 19:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-502079-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.145718 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved