【问题标题】:Convert one-hot encoding to plain binary将 one-hot 编码转换为纯二进制
【发布时间】:2014-01-19 02:00:37
【问题描述】:

这不是一个常规的“binary to bcd”问题,事实上,我真的不知道该怎么称呼我正在尝试做的事情!

嵌入式设备中有一个字节以下列格式存储数字 1 到 7(一周中的几天):

00000001 = 1
00000010 = 2
00000100 = 3
00001000 = 4
00010000 = 5
00100000 = 6
01000000 = 7

我想读取这个字节,并将其内容(1 到 7)转换为 BCD,但我不知道该怎么做。

我知道我可以通过一系列 if 语句来暴力破解它:

if(byte == B00000001) 
{
    answer = 1; 
}
else
if(byte == B00000010) 
{
    answer = 2; 
}

等等,但我认为可能有更好的方法。该数据存储在实时时钟上的单个寄存器中。我通过执行 I2C 读取来获取此字节,并将其读入程序中的一个字节。此实时时钟的数据表指定此特定寄存器的格式如我上面所述。

【问题讨论】:

  • 你有没有尝试过?
  • 我知道我可以用一系列 if 语句强制它 if(byte == 00000001) answer = 1;如果(字节== 00000010)答案= 2;等等,但我认为可能有更好的方法。此数据存储在实时时钟上的单个寄存器中
  • 提示:你有二的升幂
  • @EdHeal: "单字节"
  • @DylanCrockern 01000000b 不是 7

标签: c++ one-hot-encoding


【解决方案1】:

您可以使用查找表...

/* this is only needed once, if lut is global or static */
unsigned char lut[65];
lut[1]=1;
lut[2]=2;
lut[4]=3;
lut[8]=4;
lut[16]=5;
lut[32]=6;
lut[64]=7;

...
...
...

/* Perform the conversion */
answer = lut[byte];

或者你甚至可以使用一些数学......

answer = 1 + log(byte)/log(2);

【讨论】:

  • 我什至没有使用对数!这看起来是最容易实现的,谢谢!
  • 转念一想,由于我正在研究嵌入式系统,因此速度非常重要。你知道上面列出的哪种方法对于 8 位 16MHz 处理器来说会更快完成吗?我有一种感觉,计算2个对数和一个除法会比查找表花费更长的时间
  • @user3211203 看看我在你的问题上留下的链接。这是计算以 2 为底的整数对数的最快方法。
  • @user3211203 :毫无疑问,第一种(LUT)方法。您可以将 LUT 放在代码存储器中,代码存储器通常比数据存储器大。如果您在声明中对其进行初始化,它将仅从第一个时钟周期开始准备就绪。要使用它,它只是使用索引读取代码存储器,这可能需要几个周期(在 8051 级微控制器上大约需要 4-5 个周期)
【解决方案2】:

如果这是在 ARM 处理器上编译的,您可以这样做:

result = 31 - __CLZ(number);

假设number32-bit one-hot > 0

【讨论】:

    【解决方案3】:

    您可以利用按位和模运算来有效地执行此操作,而无需创建大型数组

    for (int answer = 1; (byte % 2) == 0; ++answer) {
        byte >>= 1;
    }
    

    (我知道这是一个老问题,我只是想分享一下,因为这对我来说是一个很高的 Google 结果)

    【讨论】:

      猜你喜欢
      • 2021-08-19
      • 1970-01-01
      • 2018-01-26
      • 2023-03-13
      • 2022-01-22
      • 2019-09-27
      • 1970-01-01
      • 2017-07-27
      相关资源
      最近更新 更多