首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >符号位为1的原因,即使我们把正数分为双型。

符号位为1的原因,即使我们把正数分为双型。
EN

Stack Overflow用户
提问于 2019-04-14 06:14:24
回答 3查看 73关注 0票数 0

我把正值放入变量中,哪种类型是双倍的。当我看到内存的内容时,符号位是1,我认为应该是0,但它可能是错的。为什么符号位是1?

代码语言:javascript
复制
#include<stdio.h>

int main(){
    int num=116;

    union {float x; int i;} u4;
    union {double x; long long int i;} u8;

    u4.x = (float) num/10000.0;
    u8.x = (double) num/10000.0;

    printf("%lx\n",u4.i);
    printf("%lx\n",u8.i);

    printf("%.30f\n",u4.x);
    printf("%.30f\n",u8.x);

    return 0;
}

输出:

代码语言:javascript
复制
3c3e0ded
a5119ce0
0.011599999852478504000000000000
0.011599999999999999000000000000

a5119ce0是双类型的输出。a5119ce0意味着

1010 0101 0001 0001 1001 1100 1110 0000

它的符号位是1,这是负数。

3c3e0ed是浮子类型的输出。3c3e0d

0011 1100 0011 1110 0000 1101 1110 1101

我也感到困惑的是,相同长度的结果是用浮动和双。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-04-14 06:21:23

你印错了。记住,C对printf的输入没有任何假设。您指定了%lx来打印双字节,实际上只打印前32个字节。您应该使用%ll打印64位整数(在C中称为long long)。

要理解打印了哪32位的双面,你还必须理解大端和小端。基本上,不同的CPU将最不重要的位放在第一位或最后一位,这意味着取决于目标CPU,您将得到最小的32位或最重要的位。x86和x64 (您可能正在运行代码)是小endian。

票数 2
EN

Stack Overflow用户

发布于 2019-04-14 06:31:36

如果您在编译时发出警告,编译器可能会指出您的错误。使用gcc

代码语言:javascript
复制
$ gcc -Wall main.c 

main.c: In function ‘main’:
main.c:12:12: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
     printf("%lx\n",u4.i);
            ^
main.c:12:12: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
main.c:13:12: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘long long int’ [-Wformat=]
     printf("%lx\n",u8.i);
            ^
main.c:13:12: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘long long int’ [-Wformat=]

所作更正表明:

代码语言:javascript
复制
printf("%x\n",u4.i);
printf("%llx\n",u8.i);

在没有警告的情况下编译并生成预期的输出:

代码语言:javascript
复制
3c3e0ded
3f87c1bda5119ce0
0.011599999852478504180908203125
0.011599999999999999200639422270
票数 3
EN

Stack Overflow用户

发布于 2019-04-14 06:29:51

下面是您的代码的一个修改版本,用于打印存储在内存中的IEEE-754格式的浮点值。注意对大端和小端的快速而肮脏的测试,这影响了我们打印的方式:

代码语言:javascript
复制
int main()
{
    unsigned int test = 0x01020304;
    int isBigEndian = (1 == *(char*)&test);
    float num = 3.14;

    // breaking the rules here, but this will work for demonstration purposes
    unsigned char* ptr = (unsigned char*)&num

    // we're assuming sizeof(float) == 4
    if (isBigEndian)
        printf("0x%02x%02x%02x%02x\n", ptr[0], ptr[1], ptr[2], ptr[3]);
    else
        printf("0x%02x%02x%02x%02x\n", ptr[3], ptr[2], ptr[1], ptr[0]);

    return 0;

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55672469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档