【问题标题】:Reverse / Mirror 64 bits with a look up table in C使用 C 中的查找表反转/镜像 64 位
【发布时间】:2021-03-15 18:57:18
【问题描述】:

我正在尝试实现一个功能:

  • 创建一个包含 256 个反转整数的查找表(table[1] 将包含 100000002)。
  • 接收一个 8 字节的值,该值被拆分为 1 字节的块。
  • 查找每个 8 位块以获取其反转位,并且
  • 连接位并将连接后的值分配给一个 8 字节的变量,该变量将作为函数的返回值。

我的代码:

#include <stddef.h>


typedef size_t bitsarr_ty;  /* Assuming 64-bit system - size of 8 bytes */

typedef enum
{
    NOT_INITIALIZED,
    INITIALIZED
} mirrored_lut_status_ty;

static int mirrored_bits_lut[256] = {0};



bitsarr_ty BitArrayMirror(bitsarr_ty bitarr);

mirrored_lut_status_ty mirrored_lut_status = NOT_INITIALIZED;

/******************************* InitMirroredLUT **********************/

void InitMirroredLUT()
{
    size_t integer_value = 0;

    for (integer_value = 0; integer_value < 256; ++integer_value)
    {
        mirrored_bits_lut[integer_value] = BitArrayMirror(integer_value);
    }
}

/******************************* BitArrayMirror **********************/

bitsarr_ty BitArrayMirror(bitsarr_ty bitarr)
{
    size_t curr_bit_index = 0;  
    bitsarr_ty mirrored_bitarr = 0; 

    for (curr_bit_index = 0; curr_bit_index < 64; ++curr_bit_index) 
    { 
        if((bitarr & (1UL << curr_bit_index)))
        {
            mirrored_bitarr |= 1UL << ((64 - 1) - curr_bit_index); 
        }  
    } 

    return(mirrored_bitarr); 
}

bitsarr_ty BitArrayMirrorLUT(bitsarr_ty bitarr)
{
    bitsarr_ty mirrored_bitarr = 0;

    if (NOT_INITIALIZED == mirrored_lut_status)
    {
        InitMirroredLUT();
        mirrored_lut_status = INITIALIZED;
    }

    mirrored_bitarr = mirrored_bits_lut[bitarr & 0xff] << 56 |
        mirrored_bits_lut[(bitarr >> 8) & 0xff] << 48 |         
        mirrored_bits_lut[(bitarr >> 16) & 0xff] << 40 |
        mirrored_bits_lut[(bitarr >> 24) & 0xff] << 32 |         
        mirrored_bits_lut[(bitarr >> 32) & 0xff] << 24 |
        mirrored_bits_lut[(bitarr >> 40) & 0xff] << 16 |
        mirrored_bits_lut[(bitarr >> 48) & 0xff] << 8 |            
        mirrored_bits_lut[(bitarr >> 56) & 0xff];

    return (mirrored_bitarr);
}

它编译并运行时输出错误。

对于以下输入:

0000000000000000000000000000010000000000000000010000000000000000

我得到以下输出:

0000000000000000000000000000000000000000000000000000000000000000

还有以下错误:

In function ‘BitArrayMirrorLUT’:
source/bit_array.c:321:53: warning: left shift count >= width of type [-Wshift-count-overflow]
  321 |  mirrored_bitarr = mirrored_bits_lut[bitarr & 0xff] << 56 |
      |                                                     ^~
source/bit_array.c:322:49: warning: left shift count >= width of type [-Wshift-count-overflow]
  322 |         mirrored_bits_lut[(bitarr >> 8) & 0xff] << 48 |
      |                                                 ^~
source/bit_array.c:323:50: warning: left shift count >= width of type [-Wshift-count-overflow]
   |         mirrored_bits_lut[(bitarr >> 16) & 0xff] << 40 |
      |                                                  ^~
source/bit_array.c:324:50: warning: left shift count >= width of type [-Wshift-count-overflow]
   |         mirrored_bits_lut[(bitarr >> 24) & 0xff] << 32 |

我的错误是什么?

【问题讨论】:

  • 您的查找表存储有符号整数,通常为 32 位宽。如果要将它们移动超过 31 位,则应将其转换为 bitsarr_ty。这就是警告告诉你的。 (顺便说一下,&lt;stdint.h&gt; 具有指定宽度的整数,例如 uint64_t,这在这里可能很有用。)
  • BitArrayMirror 变化太多。您正在使用它来初始化 8 位反转表,但它试图在 64 位字段中反转。
  • @MOehm 感谢您的回答,但不幸的是,当我尝试在每行(最后几行)的开头将其转换为 (bitsarr_ty) 时,它并没有帮助。
  • 它修复了警告,不是吗?这就是我的评论。这只是一个评论,而不是一个答案。 Tsanisl 已经回答了您的真正问题。

标签: arrays c bit-manipulation bit lookup-tables


【解决方案1】:

因为在计算 mirrored_bits_lut 时,您将 8 位数字反转为 64 位数字。转换为 32bit int 时忽略所有重要位

【讨论】:

  • 哦,知道了。那么我应该将查找表设为 64 个元素来解决这个问题吗?
  • @NoobCoder: 不。使表格成为unsigned charuint8_t 元素的表格,并将BitArrayMirror 中的64 更改为8 在它出现的两个位置。在BitArrayMirrorLUT 中,将每个mirrored_bits_lut[…] 更改为(bitsarr_ty) mirrored_bits_lut[…]
  • @EricPostpischil 谢谢,它有效!但是.. 是否有一个选项可以使它工作,同时保持648 位参数的BitArrayMirror 选项单一,而不是复制它并将64 更改为8?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
  • 2020-04-07
  • 2011-09-12
  • 2019-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多