通过连接将位(字节)存储在 long long 中

Posted

技术标签:

【中文标题】通过连接将位(字节)存储在 long long 中【英文标题】:store bits(byte) in long long by concatenation 【发布时间】:2017-08-10 17:41:54 【问题描述】:

poly8_bitslice() 数组如果char 作为输入,这个输入将被函数intToBits() 转换为位(字节)。

转换后,我想将结果存储在long long 变量中。这可能吗? 我可以连接intToBits()的结果吗?

我想用下面的代码做到这一点:

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <string.h>
//#include <math.h>

typedef unsigned char poly8;
typedef unsigned long long poly8x64[8];

void intToBits(unsigned k, poly8 nk[8]) 
    int i; 
    for(i=7;i>=0;i--)        
        nk[i] = (k%2);        
        k = (int)(k/2);
    


void poly8_bitslice(poly8x64 r, const poly8 x[64])

  //TODO
    int i;
    for(i=0;i<64;i++)
        poly8 xb[8];
        intToBits(x[i], xb);
        int j;
        long long row;
        for(j=0;j<8;j++)
            row = row + x[j];
        

        printf("row=%d \n", row);         
    


int main()


  poly8 a[64], b[64], r[64];
  poly8x64 va, vb, vt;
  int i;

  FILE *urandom = fopen("/dev/urandom","r");
  for(i=0;i<64;i++)
  
    a[i] = fgetc(urandom);
    b[i] = fgetc(urandom);
  

  poly8_bitslice(va, a);
  poly8_bitslice(vb, b);

  fclose(urandom);
  return 0;

【问题讨论】:

k = (int)(k/2); 中,您为什么要将未签名的内容转换为已签名的内容? 您应该包含inttypes.h 并使用所有固定宽度类型,而不是自己编造。使用 uint8_t 和 unit64_t。 long long row; ... printf("row=%d \n", row); 不使用匹配的说明符。使用 printf("row=%lld \n", row); 并启用所有编译器警告 - 这应该告诉你。 您要哪种类型的? long long 如“我想将结果存储在 long long 变量中”或 unsigned long longunsigned long long poly8x64[8];? 【参考方案1】:

我不确定我是否完全理解你的问题,但你可以这样做

char ch0 = 0xAA;
char ch1 = 0xBB;
char ch2 = 0xCC;
char ch3 = 0xDD;
long long int x = 0;           // x is 0x00000000
x = (long long int)ch0;        // x is 0x000000AA
x = x << 8;                    // x is 0x0000AA00
x = x | (long long int)ch1;    // x is 0x0000AABB
x = x << 8;                    // x is 0x00AABB00
x = x | (long long int)ch2;    // x is 0x00AABBCC
x = x << 8;                    // x is 0xAABBCC00
x = x | (long long int)ch3;    // x is 0xAABBCCDD

在这种情况下,x 将包含0xAABBCCDD

&lt;&lt; 运算符将左手运算符的内容移动右手运算符指定的数字。所以0xAA &lt;&lt; 8 会变成0xAA00。请注意,它会在移位时在末尾附加零。 | 运算符将按位或在其两个操作数上执行。那是一点点或。因此,左手运算符的第一位将与右手运算符的第一位进行或运算,结果将放在结果的第一位。 任何结果都为零的东西,所以

0xAA00 | 0x00BB

会导致

0xAABB

一般来说有点追加功能是

long long int bitAppend(long long int x, char ch) 
    return ((x << 8) | (long long int)ch);

此函数将采用您需要附加到的 long long 整数和要附加到它的 char,并返回附加的 long long int。请注意,一旦 64 位被填满,高位将被移出。

例如

long long int x = 0x1122334455667788
x = x << 8;    // x now is 0x2233445566778800

这将导致 x 为 0x2233445566778800,因为 long long int 中只有 64 位,因此高位必须移出。

【讨论】:

x = (long long int)ch0;等中当然不需要强制转换。符号位左移是UB。

以上是关于通过连接将位(字节)存储在 long long 中的主要内容,如果未能解决你的问题,请参考以下文章

请问C语言中float,long,int等是怎么区分范围的

Java中char,short,int,long占几个字节和多少位

在C语言中定义二维数组long a[3][5],则数组占多少字节的存储空间?

SQLite 中是不是有 Long 类型?

为啥 double 可以存储比 unsigned long long 更大的数字?

在 C99 中:如何访问 long double 变量中的特定字节