c - 使用按位运算(非 float )缩放 4 位数字

标签 c floating-point integer bit-manipulation microcontroller

我想知道如何将浮点变量“增益”值(十进制 0.0 - 1.0)乘以变量 4 位离散值(16 个离散级别)以最终得到缩放值,所有这些都不使用浮点-点数学/数字(最好使用按位运算等)。我正在用 C(XC16 编译器)对 PIC 16 位微 Controller 进行编程,以控制彩色 LED 阵列。每个 LED 可以呈现 16 级强度。 P 是该瞬间的原始 LED“模式”强度。 C 是应用于 P 的图案比例值。S 是最终缩放的图案值。

例如,我有一个值 P = 0x0F,我想将其缩放为其原始值的 50%(即乘以 C = 0.50),最终得到“S”= 0x08(向上舍入);或 P = 0x00:0x0F 且 C = 0.0:1.0 的任意组合。结果“S”最终应为 4 位数字(16 个离散值,0x00 到 0x0F),但根据“C”缩放原始值的 0-100%。显然,必须采用一些天花板/地板/舍入方法,也许还需要一些类型转换。

有什么想法吗?这看起来很容易,但我遇到了麻烦。如果一切都失败了,我可以使用浮点运算来完成它。但是,我喜欢使用更有效的方法(并学习一些东西)的想法,而不是用 float 和舍入来强制执行。

*因子“C”可以是缩放(或标准化)“P”的任何值,至少需要一个仅使用较低半字节的短整型(BYTE)类型,分为 16 个级别; 0/15 至 15/15。 'P' 已经是一个 4 位数字,但我想对其应用“增益”以将其从给定值缩小(可以是 0/15 到 15/15),或者如果增益保持不变值 = 100%。例如,如果 P = 15/15 (0x0F) 并且 C = 100%,则 S = 15/15 (0x0F)。现在,如果 P = 8/15 (0x07) 且 C = 50%,则 S = 4/15 (0x03)。如果 P = 0,则所有 S = 0。如果 C = 0,则所有 S = 0。对于 P > 0 且 C > 0 但 S = 0 的情况(即 P 和 C 的值较低),我将有一个条件设置 S = 1 (1/15 = 0x01)。此条件是特定于问题的。

最佳答案

正 float 随着其解释为整数的表示位数的增加而增加。如果您希望避免浮点运算,可以在 1/16、2/16、3/16、4/16 表示的位数组中对输入表示的第 th 位进行二分搜索,...

union u { float f; uint32_t u; } tbl[] = { 0.0f, 0.0625f, 0.125f, … };

int convert_to_4_bits(float f) {
  union u v;
  v.f = f;
  int i;
  /* binary search of v.u in tbl, 
       using 4 32-bit integer comparisons, 
       leaving result in i */
  if (v.u >= tbl[8].u)
    i = 8;
  else
    i = 0;
  if (v.u >= tbl[i+4].u)
    i += 4;
  if (v.u >= tbl[i+2].u)
    i += 2;
  if (v.u >= tbl[i+1].u)
    i += 1;
  return i;
}

我将让您决定边缘情况(即 tbl 中的确切值以及是否使用 >=>用于比较。请注意,从未使用过 tbl[0],因此您可以在此处进行一些优化,但会损害简单性。

您在问题中说您希望使用按位运算。没问题:将程序中所有+=替换为|=

关于c - 使用按位运算(非 float )缩放 4 位数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26287720/

相关文章:

c - 查找最大数字在数组中出现的次数

php - 更正浮点值

java - 如何在java中将字符串解析为具有三位小数的 float

C#:如何使整数为负数?

c++ - 如何翻译 GTK+ 应用程序?

c - 如何在 onc-rpc 中将字符串 (char*) 从服务器发送到客户端

java - 将 2,4,5,6,7,8,10,12,14,15,16 等字符串转换为 2,4-8,10,12,14-16

python - 我如何着手模拟 Python 中的按引用传递的等价物?

c - PIC 和 XC8 编译器问题

使用c语言在linux可加载内核模块中将字符串转换为 float