【问题标题】:Converting binary int to binary uint8_t in c在c中将二进制int转换为二进制uint8_t
【发布时间】:2019-03-18 11:53:33
【问题描述】:

我有一个数组定义为

int data[k];

其中 k 是数组的大小。数组的每个元素都是 0 或 1。我想将二进制数据保存在另一个定义为

的数组中
uint8_t new_data[k/8];

(k 通常是 8 的倍数)。
如何在 C 中做到这一点?

提前致谢

【问题讨论】:

  • "向量的每个元素都是二进制的。"你的意思是每个元素是0还是1? k 是否保证是 8 的倍数?
  • 数组,不是向量。
  • 还有:这些位应该按什么顺序打包?
  • 不清楚你在问什么......在所有其他与 C 中的序列化相关的问题中,在写这个答案之前你尝试过什么?您是否尝试将模/除或二进制和/左移与赋值结合使用?
  • 如果您没有想到任何这些想法,为什么不呢?你在看哪本书?你在看书,对吧?因为把 C 当作一个“神秘的黑匣子”来学习是很危险的;您最终学习的不是 C,而是 C 的某些子集,当您将其迁移到不同的系统配置或出于其他一些琐碎的原因(如操作系统更新)时,它会出现异常行为......这个问题还有其他恶魔......你需要花时间编辑你的问题,起草它,就像你将它提交给一个团队进行审查并接受审查......因为就目前而言,至少可以说是令人困惑的。

标签: c binary int hex uint8t


【解决方案1】:

假设new_data 从 0 开始初始化,data[i] 只包含 0 和 1,并且您想先填充最低位:

for(unsigned i = 0; i < k; ++i) {
    new_data[i/8] |= data[i]<<(i%8);
}

一个可能更快的实现1可能是:

for(int i = 0; i < k/8; ++i) {
    uint8_t o = 0;
    for(int j = 0; j < 8; ++j) {
        o |= data[i*8]<<j;
    }
    new_data[i] = o;
}

(请注意,这实际上假设k 是 8 的倍数)


  1. 通常更容易优化,因为内部循环具有已知的小边界,并且它写入的变量只有那么小范围;这对优化器来说更容易处理,例如,您可以通过 gcc the inner loop gets completely unrolled 看到。

【讨论】:

  • @autistic:OP 说“向量的每个元素都是二进制的”,所以我假设它是 0 或 1;如果不是这样,在data[i] 前面添加!! 将解决此问题(但可能会减慢速度)。
  • 嘿...够公平...这个问题的另一个原因...需要更多时间。那个词“二进制”;它不再具有相同的单一含义。我想知道为什么 OP 还标记了 [hex]...
  • 我注意到您在回答之前询问了这个问题(并且 OP 尚未回答),前提是您确定......所以为什么要问?我认为人们会滥用 StackOverflow 是有道理的,因为它现在是一个竞争性网络。不过,在我看来,在您不确定时回答似乎总是违背网络的精神......
  • 另外,这个问题被标记为[C] 而不是[gcc]。 “本国际标准中的语义描述描述了与优化问题无关的抽象机器的行为。” --C11/5.1.2.3p1; “在抽象机器中,所有表达式都按照语义的规定进行评估。” --C11/5.1.2.3p4。 C 没有强制要求进行优化,此外,它甚至可能不是优化;它不相关且无效;在这个答案中没有必要提及它。
  • @autistic:这只是迂腐;一个人为编译器编写代码,而不是抽象的。第二个提议不仅仅是针对 gcc 量身定制的(这只是一个示例),它总体上对编译器更友好,因为编译器可以很容易地看穿内部循环(它已知,更小的边界并且适用于具有小范围的局部变量);尝试使用其他编译器,您会发现在几乎所有情况下,它们都会设法生成更智能的代码。话虽如此,我还是稍微改写了那部分以纳入这个解释。
【解决方案2】:

假设k8 的倍数,假设“每个元素都是二进制”,您的意思是“每个int 要么是0 要么是1”,同样假设data 中的位从最高有效到最低有效打包,new_data 的字节被打包为大端(所有合理的假设),那么你就是这样做的:

for (int i = 0; i < k/8; ++i)
{
    new_data[i] = (data[8*i  ] << 7) | (data[8*i+1] << 6)
                | (data[8*i+2] << 5) | (data[8*i+3] << 4)
                | (data[8*i+4] << 3) | (data[8*i+5] << 2)
                | (data[8*i+6] << 1) | data[8*i+7];
}

【讨论】:

  • 这个答案有很多假设。将来,请要求澄清,因为这甚至可能无法回答预期的问题。
猜你喜欢
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
  • 2016-10-12
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
相关资源
最近更新 更多