2013-03-20 148 views
1

爲什麼我在下面的代碼中得不到正常的結果?變量類型混亂

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

我錯過了什麼?

+0

255用於pwmCycleDutyA – kyrpav 2013-03-20 14:05:02

+0

預定數量這不是沒有C代碼。 – fuz 2013-03-20 14:20:57

回答

3

問題是float x = percentage/100,其中percentageint類型。這意味着/的兩個參數都是整數,因此執行整數除法。然後,結果轉換爲float

你想這樣的:

float x = percentage/100.f; 

或者只是改變的percentage類型float

5

這裏:

float x=percentage/100; 

您正在執行整數除法(因爲兩個操作數是整數)。這意味着結果將是0每次percentage小於100。這解釋了你所得到的結果。

更改成:

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

或者:

float x=percentage/100.f; 
+0

如果我們這樣做:int x = 3 int y = 5和float z = x/y這意味着z將不正確? – kyrpav 2013-03-20 14:07:51

+1

@kyrpav:取決於「正確」的含義:對於語言規則,這是正確的:)如果要執行浮點除法,則其中一個操作數需要爲浮點數。如果你有整數變量,就至少在其中的一個上使用'static_cast ',正如我在答案中所顯示的那樣 – 2013-03-20 14:09:20

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位整數(C允許的最小值)。