Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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++ - Fatal编程技术网

C++ 将整型位转换为浮点型并逐字打印

C++ 将整型位转换为浮点型并逐字打印,c++,C++,我只是想复制一个32位无符号int的内容,用作float。不是强制转换,只是重新解释要用作浮点的整数位。我知道memcpy是最受欢迎的选择。然而,当我从uint_32将memcpy转换为float并打印出各个位时,我发现它们有很大的不同 以下是我的代码片段: #include <iostream> #include <stdint.h> #include <cstring> using namespace std; void print_bits(unsi

我只是想复制一个32位无符号int的内容,用作float。不是强制转换,只是重新解释要用作浮点的整数位。我知道memcpy是最受欢迎的选择。然而,当我从uint_32将memcpy转换为float并打印出各个位时,我发现它们有很大的不同

以下是我的代码片段:

#include <iostream>
#include <stdint.h>
#include <cstring>

using namespace std;

void print_bits(unsigned n) {
  unsigned i;
  for(i=1u<<31;i > 0; i/=2)
    (n & i) ? printf("1"): printf("0");
}

union {
    uint32_t u_int;
    float u_float;
} my_union;

int main()
{
    uint32_t my_int =  0xc6f05705;
    float my_float;
    //Method 1 using memcpy
    memcpy(&my_float, &my_int, sizeof(my_float));
    //Print using function
    print_bits(my_int);
    printf("\n");
    print_bits(my_float);
    //Print using printf
    printf("\n%0x\n",my_int);
    printf("%0x\n",my_float);
    //Method 2 using unions
    my_union.u_int = 0xc6f05705;
    printf("union int = %0x\n",my_union.u_int);
    printf("union float = %0x\n",my_union.u_float);
    return 0;
}

有人能解释发生了什么事吗?我希望这些位子能匹配。也无法使用联合。

您需要将函数print\u bits更改为

inline
int is_big_endian(void)
{
    const union
    {
        uint32_t i;
        char c[sizeof(uint32_t)];
    } e = { 0x01000000 };

    return e.c[0];
}

void print_bits( const void *src, unsigned int size )
{
    //Check for the order of bytes in memory of the compiler:
    int t, c;
    if (is_big_endian())
    {
        t = 0;
        c = 1;
    }
    else
    {
        t = size - 1;
        c = -1;
    }
    for (; t >= 0 && t <= size - 1; t += c)
    {   //print the bits of each byte from the MSB to the LSB
        unsigned char i;
        unsigned char n = ((unsigned char*)src)[t];
        for(i = 1 << (CHAR_BIT - 1); i > 0; i /= 2)
        {
            printf("%d", (n & i) != 0);
        }
    }
    printf("\n");
}
这样,当您调用print_位时,就不会有任何类型转换,并且它适用于任何结构大小

编辑:我用CHAR_位-1替换了7,因为字节的大小可以不同于8位

编辑2:我增加了对little-endian和big-endian编译器的支持


另外,正如@M.M在注释中建议的那样,如果您愿意,您可以使用模板使函数调用为:
print\u bits(a)
而不是
print\u bits(&a,sizeof(a))

一个问题(可能还有其他问题)是,在
print\u bits(my\u float)中调用时,编译器将知道函数需要一个
无符号整数
,因此,将首先将
浮点
变量转换为其(截断的)
无符号整数
表示形式,然后再将其值放入参数堆栈。当调用
打印位(my\u float)时
它执行浮点到整数的数字转换。因此,
1.0
被转换为整数
1
,而不是包含浮点数表示形式的整数。您可以使用
reinterpret\u cast(my\u float)
来获得所需的转换。@Barmar实际上不,您不能。你可以投下指针,但那是错误的
memcpy
确实是解决这个问题的方法。而且,
400865
vs
40086b
问题(在我的Window/clang cl系统上不可复制)看起来像是一个与endianness相关的问题。“结束”半字节是0101和1101,因此“符号位”可能存在干扰。你使用什么平台/编译器?当然最好使用模板,然后调用方可以做<代码> PrttLyBub(A)< /Calp> @ M.M。我想你可以,因为我看到OP使用了PrtTF,我用C风格写了它而不是C++。我个人也不认为这有多重要,通过这种方式,您可以更自由地传递任何指针(包括void*)并选择任何大小。
inline
int is_big_endian(void)
{
    const union
    {
        uint32_t i;
        char c[sizeof(uint32_t)];
    } e = { 0x01000000 };

    return e.c[0];
}

void print_bits( const void *src, unsigned int size )
{
    //Check for the order of bytes in memory of the compiler:
    int t, c;
    if (is_big_endian())
    {
        t = 0;
        c = 1;
    }
    else
    {
        t = size - 1;
        c = -1;
    }
    for (; t >= 0 && t <= size - 1; t += c)
    {   //print the bits of each byte from the MSB to the LSB
        unsigned char i;
        unsigned char n = ((unsigned char*)src)[t];
        for(i = 1 << (CHAR_BIT - 1); i > 0; i /= 2)
        {
            printf("%d", (n & i) != 0);
        }
    }
    printf("\n");
}
int a = 7;
print_bits(&a, sizeof(a));