为什么#define中的除法导致代码中的除法输出不同的答案

时间:2019-12-04 22:53:22

标签: arduino

我得到的速度值比我计算的值小4倍,并将其范围缩小到车轮半径的倒数。我最初有WHEEL_D_OVER_TWO,在做倒数时,我得到的答案不正确(相差4倍)。我已经在下面的代码中复制了该问题。

硬件是Arduino UNO。

#define WHEEL_RADIUS 30.0
#define WHEEL_D_OVER_TWO 60.0 / 2.0

void setup() { Serial.begin(115200); }

void loop() {
  Serial.println("WHEEL_RADIUS : " + String(WHEEL_RADIUS, 8));
  Serial.println("Inverse WHEEL_RADIUS : " + String(1.000 / WHEEL_RADIUS, 8));
  Serial.println("WHEEL_D_OVER_TWO : " + String(WHEEL_D_OVER_TWO, 8));
  Serial.println("Inverse WHEEL_D_OVER_TWO : " +
                 String(1.000 / WHEEL_D_OVER_TWO, 8));
  delay(1000);
}

以上代码的输出为

WHEEL_RADIUS : 30.00000000
Inverse WHEEL_RADIUS : 0.03333334
WHEEL_D_OVER_TWO : 30.00000000
Inverse WHEEL_D_OVER_TWO : 0.00833333

Inverse WHEEL_RADIUS使用计算器是正确的。我搜索的大多数问题都是整数除法,我想我在这里避免。我知道当前的解决方法,但是我想知道这个示例给我不同的答案的根本原因。

谢谢。

1 个答案:

答案 0 :(得分:2)

宏仅仅是文本替换。您的WHEEL_D_OVER_TWO被定义为

#define WHEEL_D_OVER_TWO 60.0 / 2.0

这意味着

1.000 / WHEEL_D_OVER_TWO

扩展为

1.000 / 60.0 / 2.0

由于C和C ++中的/运算符从左到右关联,因此被解释为

(1.000 / 60.0) / 2.0

很显然,这与

远不相同
 1.000 / WHEEL_RADIUS

(这显然是您所期望的)。

这就是为什么在将宏定义为表达式时,记住将其括起来很重要

#define WHEEL_D_OVER_TWO (60.0 / 2.0)

这将使您免于此类意外。

一个更好的主意(至少在C ++中)是使用const变量而不是宏,然后完全忽略此问题

const double WHEEL_D_OVER_TWO = 60.0 / 2.0;