C 为什么符号位为1,即使我们将正分数放入双精度类型

C 为什么符号位为1,即使我们将正分数放入双精度类型,c,C,我把正值放入变量中,它的类型是double。 当我看到内存的内容时,符号位是1。 我认为应该是0,但可能是错的。 为什么符号位是1 包括 int main{ int num=116; 并集{float x;int i;}u4; 并集{double x;long long int i;}u8; u4.x=浮点数/10000.0; u8.x=双数/10000.0; printf%lx\n,u4.i; printf%lx\n,u8.i; printf%.30f\n,u4.x; printf%.30f\

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

包括 int main{ int num=116; 并集{float x;int i;}u4; 并集{double x;long long int i;}u8; u4.x=浮点数/10000.0; u8.x=双数/10000.0; printf%lx\n,u4.i; printf%lx\n,u8.i; printf%.30f\n,u4.x; printf%.30f\n,u8.x; 返回0; } 输出:

3c3e0ded
a5119ce0
0.011599999852478504000000000000
0.011599999999999999000000000000
a5119ce0是双类型的输出。 a5119ce0表示 1010 0101 0001 0001 1001 1100 1110 0000 它的符号位是1,这意味着这是一个负数

3c3e0ded是浮点型的输出。 3c3e0ded方法 0011100 0011110 0000 1101 1110 1101


我也很困惑,用float和double得到的长度结果是一样的。

你打印错了。记住,C对printf的输入不作任何假设。您正在指定%lx打印双精度,实际上只打印前32个字节。您应该使用%ll将C中已知的64位整数打印为最长


要理解打印的是哪32位双精度,还必须理解大端和小端。基本上,不同的CPU将最低有效位放在第一位或最后一位,这意味着根据目标CPU的不同,您将获得最低有效位32位或最高有效位。您可能正在运行代码的x86和x64是little endian BTW。

这里是您代码的一个修改版本,用于以IEEE-754格式打印浮点值作为其存储在内存中的格式。请注意big-endian和little-endian的快速脏测试,这会影响打印方式:

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;

}

如果编译时打开了警告,编译器可能会指出错误。例如,对于gcc:

作出指示的更正:

printf("%x\n",u4.i);
printf("%llx\n",u8.i);
编译时没有警告,并生成预期输出:

3c3e0ded
3f87c1bda5119ce0
0.011599999852478504180908203125
0.011599999999999999200639422270

但有一点:您实际上是在堆栈上复制64位数据,以便printf读取。它将读取32位来打印一个长字符。它得到哪32位取决于哪32位先到。实际上,使用说明符%llx会导致输出3f87c1bda5119ce0,这是正数,表明机器是little endian。如果是big endian,符号位应该是正确的。谢谢!!你的回答对我很有帮助@你知道,user703016未定义并不意味着神奇。只要您了解底层操作系统/硬件及其工作原理,就可以对发生的情况进行有根据的猜测。在这种情况下,需要理解CPU端性、函数调用和变量参数列表;但是再一次强调,用C编写代码就是要理解操作系统和硬件。如果你让它打印出任何东西,而不是双精度的一半,我很想看看代码。我很喜欢你的endianness测试。只有当机器处理浮点数的方式与int处理endianness的方式相同时,它才会起作用。据我所知,这在任何地方都不是保证或要求的。@SamiKuhmonen-正确。但世界是在英特尔和ARM体系结构上运行的:
3c3e0ded
3f87c1bda5119ce0
0.011599999852478504180908203125
0.011599999999999999200639422270