Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 按字节打印双精度值与实际值相反_C_Double_Unions - Fatal编程技术网

C 按字节打印双精度值与实际值相反

C 按字节打印双精度值与实际值相反,c,double,unions,C,Double,Unions,请查找演示我的问题的示例代码: #include<stdio.h> typedef struct { char b[8]; } byte_wise_double_t; typedef union { byte_wise_double_t bwd; double val; } DOUBLE_T; int main() { double tmp; int ii; DOUBLE_T my_val; printf("Enter a

请查找演示我的问题的示例代码:

#include<stdio.h>
typedef struct {
    char b[8];
} byte_wise_double_t;

typedef union {
    byte_wise_double_t bwd;
    double val;
} DOUBLE_T;

int main() {
    double tmp;
    int ii;
    DOUBLE_T my_val;

    printf("Enter a value:\n");
    scanf("%lf", &tmp);
    printf("The read number is: %e\n", tmp);
    my_val.val = tmp;
    printf("Printing the value bytewise:\n");
    for (ii=0; ii<8; ii++) {
        printf("%02x", (my_val.bwd.b[ii] & 0xff));
    }

    printf("\nReverse printing the value bytewise:\n");
    for (ii=7; ii>=0; ii--) {
        printf("%02x", (my_val.bwd.b[ii] & 0xff));
    }
    return 0;
}
#包括
类型定义结构{
charb[8];
}字节双字节;
typedef联合{
字节双字节bwd;
双val;
}双T;
int main(){
双tmp;
int ii;
加倍我的价值;
printf(“输入值:\n”);
scanf(“%lf”和tmp);
printf(“读取编号为:%e\n”,tmp);
my_val.val=tmp;
printf(“按字节打印值:\n”);
对于(ii=0;ii=0;ii--){
printf(“%02x”,(my_val.bwd.b[ii]&0xff));
}
返回0;
}
当您输入一个浮点值时,我按字节顺序打印双精度值,首先按预期的正确顺序打印,然后按相反的顺序打印。但事实证明,第二个print语句给出了输入double的正确十六进制表示形式。以下是一个示例输出:

Enter a value: 11.23456 The read number is: 1.123456e+001 Printing the value bytewise: 47e6913f18782640 Reverse printing the value bytewise: 402678183f91e647 输入一个值: 11.23456 读取编号为:1.123456e+001 按字节打印值: 47e6913f18782640 按字节反向打印值: 402678183f91e647
请解释为什么会发生这种情况

我认为这是一个小小的恩典对大恩典的误解

为简单起见,请看一看16位整数。比如0xaa55(十进制43605)

默认情况下,此数字与低位字节一起存储在低位插槽中,高位字节一起存储在高位插槽中

16-bit: 0xaa55

8-bit: byte[1] = 0xaa, byte[0] = 0x55;

您的第一条语句是从右向左打印十六进制,第二条语句是从左向右打印十六进制(正如您所阅读的)。看看我的小整数示例,您的第一个for循环将打印'55',然后是'aa',反转低字节和高字节。您的第二个循环将数字从高字节打印到低字节,就像您读取它一样。

您可能正在英特尔处理器上运行此代码。该处理器以小尾数顺序在内存中存储值,其中字节从最低有效字节开始存储。因此,例如,32位整数
0xdeadbeef
作为“EF BE AD DE”存储在内存中。这也扩展到了64位整数和双精度,这解释了您看到的反转

如果要按预期方式打印双精度的十六进制值,请将其与
uint64\t
合并:

typedef union {
    uint64_t intval;
    double dblval;
} DOUBLE_T;

...

DOUBLE_T my_val;
my_val.dblval = 1.2345;
printf("%016llx\n", my_val.intval);

(注意:这不是可移植的代码:它假定您可以将
double
uint64\u t
别名,但并非在所有系统上都是如此。不过,它应该适用于典型英特尔处理器上的GCC、Clang或MSVC).

但是第二个print语句给出了输入double的正确十六进制表示。您是如何得出结论的?使用十六进制到二进制转换器,结果是:
402678183f91e647=1.1234560000001017497197608E1
47e6913f18782640=2.3997742945776857759010524823E38您的计算机将double的字节存储在您在第一次打印中看到的顺序。这有时被称为little endian。据我所知,它与系统将字节中的哪个位视为MSB有关。这并不能解释字节的存储顺序。我猜是struct导致了这种行为。@Tadatmya:你的理解显然是不完整的。endianness不限于字节中的位(顺便说一句,一个字节不一定是8位)。@Tadatmya-Olaf是正确的,“endianness”不仅指位顺序为MSB,还指字节顺序。回到我的0xaa55示例,您如何知道哪个字节是MSB?谢谢你的澄清。