隐式转换或演员?

时间:2016-10-08 22:22:51

标签: c++

我有一个函数,用于交错32位字的位并返回64位结果。对于这个简单的测试用例,底部的3个字节是正确的,前5个字节的内容是不正确的。 intToBin_32和intToBin_64是方便函数,用于查看参数的二进制表示并返回val。我认为在任何地方我都需要将32位类型的转换放到64位类型,但我仍然看到这种意外(至少对我而言)行为。这里是否存在隐式转换,或者还有其他原因导致无法正常工作?

#include <stdint.h>
#include <stdio.h>

struct intString_32 {char bstr [32 + 1 + 8];};
struct intString_64 { char bstr [64 + 1 + 8];};

intString_32 intToBin_32(int a)
{
    intString_32 b;

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            if (j != 4)
            {
                b.bstr[5*i + j] = * ((a & (1 << (31 - (4*i + j)))) ? "1" : "0");
            }

            else
            {
                b.bstr[5*i + j] = 0x20;
            }
        }
    }

    b.bstr[40] = * ( "\0" );

    return b;
}

intString_64 intToBin_64(long long a)
{
    intString_64 b;

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 9; j++)
        {
            if (j != 8)
            {
                b.bstr[9*i + j] = * ((a & (1 << (63 - (8*i + j)))) ? "1" : "0");
            }

            else
            {
                b.bstr[9*i + j] = 0x20;
            }
        }
    }

    b.bstr[72] = * ( "\0" );
    return b;
}

uint64_t interleaveBits(unsigned int a, unsigned int b)
{
    uint64_t retVal = 0;

    for (unsigned int i = 0; i < 32; i++)
    {
        retVal |= (uint64_t)((uint64_t)((a >> i) & 0x1)) << (2*i);
        retVal |= (uint64_t)((uint64_t)((b >> i) & 0x1)) << (2*i + 1);
    }

    return retVal;
}

int main(int arc, char* argv)
{
    unsigned int foo = 0x0004EDC7;
    unsigned int bar = 0x5A5A00FF;
    uint64_t bat = interleaveBits(foo, bar);

    printf("foo: %s \n", intToBin_32(foo).bstr);
    printf("bar: %s \n", intToBin_32(bar).bstr);
    printf("bat: %s \n\n", intToBin_64(bat).bstr);
}

1 个答案:

答案 0 :(得分:2)

通过调试我注意到你的intToBin_64是错误的,具体来说,在这一行:

b.bstr[9*i + j] = * ((a & (1 << (63 - (8*i + j)))) ? "1" : "0");

仔细观察转变:

(1 << (63 - (8*i + j)))

文字1是一个整数,但是,将整数移位31位以上是未定义的行为。换一个longlong代替:

b.bstr[9*i + j] = * ((a & (1ll << (63 - (8*i + j)))) ? "1" : "0");