其他分享
首页 > 其他分享> > C模数需要在两个* un * signed字节之间进行减法运算,为什么?

C模数需要在两个* un * signed字节之间进行减法运算,为什么?

作者:互联网

以下Arduino(C)代码

void setup()
{
  Serial.begin(115200);
  byte b1 = 12;
  byte b2 = 5;
  const byte RING_BUFFER_SIZE = 64;

  byte diff = b2 - b1;
  byte diff2 = (byte)(b2 - b1) % RING_BUFFER_SIZE; //<---NOTE HOW THE (byte) CAST IS *REQUIRED* TO GET THE RIGHT RESULT!!!!

  Serial.println(b1);
  Serial.println(b2);
  Serial.println(RING_BUFFER_SIZE);
  Serial.println(diff);
  Serial.println(diff2);
}

void loop()
{      
}

产生预期的:

12
5
64
249
57 //<--correct answer

而没有“(byte)”演员如下所示:

void setup()
{
  Serial.begin(115200);
  byte b1 = 12;
  byte b2 = 5;
  const byte RING_BUFFER_SIZE = 64;

  byte diff = b2 - b1;
  byte diff2 = (b2 - b1) % RING_BUFFER_SIZE; //<---(byte) cast removed

  Serial.println(b1);
  Serial.println(b2);
  Serial.println(RING_BUFFER_SIZE);
  Serial.println(diff);
  Serial.println(diff2);
}

void loop()
{      
}

它产生:

12
5
64
249
249 //<--wrong answer

为什么不同?为什么模运算符只能用于显式转换?

注意:“byte”=“uint8_t”

解决方法:

5 – 12给出-7(一个int).所以你的代码做了-7%64.

在数学上我们希望这给出57.但是,在C和C中,%为负数,它没有做到你在数学上所期望的那样.相反,它满足以下等式:

(a/b) * b + a%b == a

现在,( – 7)/ 64给出0,因为C和C使用截断 – 朝向零来进行负正整数除法.因此-7%64评估为-7.

最后,将-7转换为uint8_t得到249.

当您写入(字节)-7%64时,您实际上正在做249%64给出预期的答案.

关于b2-b1的行为:所有整数运算至少以int精度完成;对于每个操作数 – ,如果它是一个比int更窄的整数类型,它首先被提升为int(保持值不变).如果在此促销后类型不同(在这种情况下他们不是这样),则可能会发生进一步的转换.

在代码中,b2 – b1表示(int)b2 – (int)b1产生一个int;没有办法指定以较低的精度执行操作.

标签:modulus,c,arduino,modulo
来源: https://codeday.me/bug/20190829/1759186.html