2013-12-15 39 views
0

我1000試圖倍52,我得到一個否定的結果Arduino的算術錯誤陰性結果

int getNewSum = 52 * 1000; 

但下面的代碼ouputting陰性結果:-13536

+1

您可能需要閱讀[關於Arduino int類型的文檔](http://arduino.cc/en/Reference/int),特別是它的限制,以及它對[two's complement]的使用(https:// en .wikipedia.org/wiki/ Two's_complement)表示。一旦你瞭解了二進制整數是如何存儲的,你就會對所發生的事情有更多的瞭解。 –

回答

1

怎樣的解釋two's complement代表作品可能在維基百科和其他地方比這裏更好。我要在這裏做的是帶你通過你的確切例子的運作。

Arduino中的int類型用16位表示,用二進制補碼錶示(請記住,其他Arduinos使用32位而不是16位)。這意味着正數和負數都可以存儲在這16位中,如果最左邊的位被設置,則該數字被認爲是負數。

發生了什麼事情是,你正在溢出你可以用來存儲一個正數的位數,並且(意外的是,就你所關心的)來設置符號位,從而表明這個數字是負數。

0000 0000 0011 0100 

(2^5 + 2^4 + 2^2 = 52)

但是,結果:

在關於您的Arduino 16位,十進制52將二進制作爲表示52000 - - 52乘以由1000的最終會溢出int的量值位,把一個在上端的符號位「1」:

*----This is the sign bit. It's now 1, so the number is considered negative. 
1100 1011 0010 0000 

(典型地,計算機整數運算和相關聯的編程語言d不會保護你免於這樣做,原因很多,主要與效率有關,現在主要與歷史有關)。

因爲左側的符號位已設置,所以要將該數字轉換回來成從假定二進制補碼錶示小數,我們假定它是一個負數,然後先取一的補(翻轉所有位):

0011 0100 1101 1111 

- 它代表13535 - 添加一個吧,產生13,536,並稱之爲負值:-13,536,你看到的價值。

如果你在一般情況下閱讀了兩個補碼/整數表達式,你會得到它的掛鉤。

與此同時,這可能意味着您應該尋找更大的類型來存儲您的號碼。 Arduino有無符號整數,和一個long類型,它將使用四個字節來存儲你的數字,給你的範圍從-2,147,483,648到2,147,483,647。如果這對你來說已經足夠了,那麼你應該改用long而不是int

0

馬特的答案已經是在發生的事情的深入的解釋非常好,但是對於那些尋找一個更實際的答案:

問題:

這種情況經常用於Arduino的程序員,當他們嘗試在正常整數(int)中賦值(=等號)乘法結果。如前所述,當結果大於編譯器分配給變量的內存大小時,會發生溢出。

解決方案1:

最簡單的辦法是考慮你的需要更大的數據類型來代替int類型。正如this tutorialspoint.com tutorial解釋有不同的整數類型,我們可以使用:

  1. INT:
    • 16位:從-32,768至32,767
    • 32位:從2,147,483,648到2,147,483,647
  2. unsigned int:從0到65,535
  3. 長:從2,147,483,648到2,147,483,647
  4. 無符號長:從0到4,294,967,295

解決方案2:

這隻有你有足夠大的分母一些分歧,在你的算術。在Arduino編譯器中,乘法是在除法之前計算的。所以如果你的公式中有一些分歧,試着用圓括號封裝它們。例如,如果您有b/c,請將其替換爲(b/c)。