变量类型一团糟

时间:2013-03-20 14:04:06

标签: c++ optimization arduino

为什么我在以下代码中没有得到正常结果?

void Motors::setCycleDutyA(int percentage) {
    Serial.println(percentage);
    Serial.println(pwmCycleDutyA);
    float x=percentage/100;
    Serial.print(x);
    pwmCycleDutyA = int(255*x);
    Serial.println(pwmCycleDutyA);
}

当我调用该函数时:

Motors::setCycleDutyA(45);

我得到了这些结果:

  

45 255 0.000

     

45 0 0.000

     

45 0 0.000

我想念什么?

3 个答案:

答案 0 :(得分:5)

下面:

float x=percentage/100;

您正在执行整数除法(因为两个操作数都是整数)。这意味着,每当0小于percentage时,结果将为100。这解释了你得到的结果。

将其更改为:

float x=percentage/static_cast<float>(100);

或者:

float x=percentage/100.f;

答案 1 :(得分:3)

问题是float x = percentage / 100,其中percentage的类型为int。这意味着/的两个参数都是整数,因此执行整数除法。然后,结果将转换为float

你想要这个:

float x = percentage / 100.f;

或者只需将percentage的类型更改为float

答案 2 :(得分:1)

对于这种情况,我倾向于避免使用浮点数。控制这样的电机的代码通常在不支持浮点的小型微控制器上运行,因此浮点计算通常在软件中进行仿真,这很慢并且可以添加相当多的额外代码。

因此,我会尝试考虑是否可以在整数数学中完成。看看序列:

float x=percentage/100;
pwmCycleDutyA = int(255*x);

这基本上相当于:

pwbCycleDutyA = percentage * 2.55;

出于很多目的,将其视为percentage * 2.5就足够了,这在整数数学中很容易呈现:

pwbCycleDutyA = (percentage * 5) / 2;

这会将我们可以生成的值的范围缩小到0..250而不是0..255 - 但请记住,由于百分比从int开始,我们只能生成100个离散值无论如何,所以很少会产生太大的(如果有的话)差异。

但是,如果您确定乘数确实需要为2.55而不是2.5,那么您也可以这样做。最明显的是简单地重新排列你的等式 - 而不是除以100然后乘以255,先乘以255,再除以100:

pwbCycleDutyA = (percentage * 255) / 100;

重新排列这样的等式时要记住的主要事情是确保防止溢出。假设percentage永远不会超过100,我们就相当安全 - 中间结果永远不会超过25500,这很容易适合签名的16位int(C允许的最小值)。