【问题标题】:Why does this binary math fail when adding 00000001, but work correctly otherwise?为什么这个二进制数学在添加 00000001 时会失败,但在其他情况下可以正常工作?
【发布时间】:2018-04-24 20:24:34
【问题描述】:

我已经尝试了所有我能想到的方法,但似乎无法让下面的二进制数学逻辑工作。不知道为什么这会失败,但可能表明我对二进制数学或 C 的误解。最终目的是将大整数(无符号长整数)作为 4 字节字直接存储到 8 位 FRAM 内存模块中,以便微控制器( Arduino)可以在断电后恢复值。因此 unsigned long 必须从它的四个字节字部分组装起来,因为它是从内存中提取出来的,组装这些字字节的算法不能正常工作。

在下面的 sn-p 代码中,long 值定义为四个字节 A、B、C 和 D(模拟从四个 8 位内存块中拉出),将其转换为十进制表示法以供使用作为安排中的无符号长整数 DDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAAA。如果 A 但是如果 B、C 或 D > 0 且 A == 1,则 A 的 1 值为算术过程中不加。值 2 有效,但值 1 无效。这有什么原因吗?还是我做二进制数学错了?这是一个需要解决方法的已知问题吗?

// ---- FUNCTIONS

unsigned long fourByte_word_toDecimal(uint8_t byte0 = B00000000, uint8_t byte1 = B00000000, uint8_t byte2 = B00000000, uint8_t byte3 = B00000000){
  return (byte0 + (byte1 * 256) + (byte2 * pow(256, 2)) + (byte3 * pow(256, 3)));
}

// ---- MAIN
void setup() {

  Serial.begin(9600);

  uint8_t addressAval = B00000001;
  uint8_t addressBval = B00000001;
  uint8_t addressCval = B00000001;
  uint8_t addressDval = B00000001;

  uint8_t addressValArray[4];
  addressValArray[0] = addressAval;
  addressValArray[1] = addressBval;
  addressValArray[2] = addressCval;
  addressValArray[3] = addressDval;

  unsigned long decimalVal = fourByte_word_toDecimal(addressValArray[0], addressValArray[1], addressValArray[2], addressValArray[3]);

  // Print out resulting decimal value
  Serial.println(decimalVal);

}

在上面的代码中,二进制值应为 00000001000000010000000100000001,也就是十进制值 16843009。但代码将十进制值计算为 16843008。 将 addressAval 的值更改为 00000000 也会计算 (正确)到 16843008,将 addressAval 更改为 00000010 也正确评估为 16843010。

我被难住了。

【问题讨论】:

  • 不要将pow 用于整数运算,例如平方和立方。 square 可能需要long long,但对于 cube 可能还不够。
  • 你考虑过转换数组而不是使用数学吗?

标签: math arduino binary addition


【解决方案1】:

问题是您使用的是pow()。这导致所有内容都被计算为二进制 32,它没有足够的精度来保存 16843009。

>>> numpy.float32(16843009)
16843008.0

解决方法是使用整数,特别是 65536 和 16777216UL。

【讨论】:

    【解决方案2】:

    不要为此使用pow()

    执行此操作的通常方法是使用移位运算符:

    uint32_t result = uint32_t(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0);
    

    【讨论】:

      猜你喜欢
      • 2016-08-15
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      • 2019-02-12
      相关资源
      最近更新 更多