c++ - 在 C++ 中将 long long 转换为字节数组并返回

标签 c++ 64-bit bit-manipulation

我已经编写了一个测试来尝试弄清楚 char[] 数组和 long long 之间的转换是如何工作的。部分出于我自己的理解,我试图找出这样做的按位方法。

从概念上讲,对于 long longchar[],下面的感觉是正确的。我向左移动,然后 AND-ing 向右移动:

for (int i = 0; i < BUFFER_SIZE; i++)
{
    buffer[i] = ((value >> (8 * i)) & 0XFF);
}

要转换回来,向左移动并对缓冲区求和:

long long recoveredValue = 0;
for (int i = 0; i < BUFFER_SIZE; i++)
{
    auto byteVal = ((buffer[i]) << (8 * i));
    recoveredValue = recoveredValue + byteVal;
}

下面是我的整个测试程序。似乎当我填写上面的第一步(在 IntToByteArray 中)时,buffer[0] 的值在“buffer[32]”处重复。我知道这里有问题,但我想不通。

请注意,对于我的应用程序,我的 BUFFER_SIZE 为 63,而我的 long long 将限制在 2^63 以下。另外,如果我将 BUFFER_SIZE 限制在 32 以下,它就可以工作。我错过了关于 64 位 int 的一个微妙之处,不是吗?但是在哪里以及如何?

// Test_BitConversion.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <cmath>


#define BUFFER_SIZE 64
unsigned char buffer[BUFFER_SIZE] = { 0 };  // This is the buffer I have available

// useful alternative method for checking conversion 
// can't use in production, because I'm moving between C++ & C#
union byteunion 
{
    long long value;
    unsigned char arr[BUFFER_SIZE];
};


// Convert long long to byte array
void IntToByteArray(long long value)
{
    for (int i = 0; i < BUFFER_SIZE; i++)
    {
        buffer[i] = ((value >> (8 * i)) & 0XFF);
    }
}

// Convert byte array to long long
long long ByteArrayToInt()
{
    long long recoveredValue = 0;
    for (int i = 0; i < BUFFER_SIZE; i++)
    {
        auto byteVal = ((buffer[i]) << (8 * i));
        recoveredValue = recoveredValue + byteVal;
    }
    return recoveredValue;
}

// Test union can convert value both directions
bool TestUnion(long long value)
{
    byteunion originalUnion, recoveredUnion;
    originalUnion.value = value;


    for (int a = 0; a < BUFFER_SIZE; a++)
    {
        recoveredUnion.arr[a] = originalUnion.arr[a];
    }

    if (recoveredUnion.value != value)
    {
        printf("Union value failed");
        return false;
    }

    return true;
}


int main()
{

    long long originalValue = 2004293008363;
    originalValue = (long long)std::pow(2, 31);
    long long recoveredValue = 0;
    byteunion originalUnion;
    originalUnion.value = originalValue;


    // Loop to find failure point
    for (int i = 1; i < BUFFER_SIZE; i++)
    {
        originalValue = (long long)std::pow(2, i);

        // First check Union method
        bool unionTest = TestUnion(originalValue);
        if (!unionTest)
        {
            printf("Fail on Union at 2^%i", i);
            break; // this is never reached - union method works
        }


        // convert value to byte array
        IntToByteArray(originalValue);

        // now convert buffer back to long long
        recoveredValue = ByteArrayToInt();


        if (originalValue != recoveredValue)
        {
            printf("Fail recoving at 2^%i\n", i);
            break;  // this is reached when the original value is 2^31
        }

    }

    printf(" OriginalValue: %llu\n", originalValue);
    printf("RecoveredValue: %llu\n", recoveredValue);

    system("pause");

    return 0;
}

最佳答案

问题在于将值转换回来。由于整数提升,这个表达式

auto byteVal = ((buffer[i]) << (8 * i));

具有类型int,而不是long long

buffer[1] 添加强制转换以解决问题:

auto byteVal = (((long long)buffer[i]) << (8 * i));

尽管使用 + 效果很好,但更常见的组合值的方法是使用 |:

recoveredValue |= byteVal;

关于c++ - 在 C++ 中将 long long 转换为字节数组并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43113387/

相关文章:

c++ - boost::numeric::quadrature 或 gsl quadrature 中的加权函数

c++ - 为什么 STL "empty"成员函数没有调用 "isEmpty"?

c++ - 如何生成 64 位掩码?

linux - 汇编 - 将字符数组转换为整数

c++ - 我如何在 C++ 中表示二进制数(用于霍夫曼编码器)?

c++ - CMake 如何检查构建目标

c++ - 矩阵乘法导致值大于 255

vb.net - 如何在 64 位应用程序和 VB2008 Express 上启用编辑并继续?

c - 在 C 中,如何使用 XOR 检查是否设置了位?

bit-manipulation - 在两个字节之间的给定点交换位