2014-07-24 30 views
0

我正在讀取一個24位值,目前變爲uint32_t變量。計算兩個這樣的變量之間的差異,並思考「它是無符號的!爲什麼這會溢出一個問題?!」,我意識到這些值已經超出了包含它們的變量的大小。C無符號整數比較 - 環繞自定義位數

這是一個計數器,所以人們知道它比另一個'大',雖然可能溢出了。因此,0x1 - 0x2 = 0xFFFFFFFF,但應該是0x00FFFFFF

我該怎麼處理這件事?

  • 定義類型uint24;
  • if/else在做適當的算術之前哪個更大;
  • 我還沒有想到的其他東西?

'最好'應該被解釋爲'最佳實踐'/'最可讀'/'最安全'。

+1

1.您能否給您所遇到的問題的例子嗎?有輸入和預期結果。 2.你想減法的結果是有符號還是無符號的? – interjay

+0

@interjay結果也是無符號的 - 這是一個計數器,所以一個是已知的更大;簽名的結果將毫無意義/ MSb浪費。 – OJFord

+0

然後我沒有看到問題是什麼。如果從較大的數字中減去較小的數字,則不會發生溢出。 – interjay

回答

6

要減去(或添加)兩個數字並使結果環繞無符號24位數字的範圍,請執行二進制操作,結果爲0xFFFFFF,即(x-y) & 0xFFFFFF。例如:

(0x1 - 0x2) & 0xFFFFFF == 0xFFFFFF 
+0

那真是愚蠢的我。 – OJFord

1

起初,你可以使用比較操作!===>>=<<=。你不需要做這樣的num1 - num2,如果你想比較...

無論如何,如果它真的necesaary,只是用位與

uint32_t n1 = 1, n2 = 5; 
printf("0x%08x", (n1 - n2) & 0x00ffffff); 

(live example)

輸出:

0x00fffffc 

如您所知,0xfffffc表示以24位有符號整數表示的-4

(請注意,2的補數是C標準規定;我的代碼可能無法在非2的補體系統的工作。)

+1

是的,它被指定爲無符號類型。 (該標準大致描述爲:令** M **爲該類型的精度,則表達式的結果爲算術正確結果模** 2^M **;這實際上是2的補碼。) – mafso

+0

@mafso是的,但嚴格來說,標準並不強制2> o < – ikh

+0

不是那個詞,是的。我的觀點是,即使在非2的補充機器上,你的代碼也能保證工作。 – mafso