簡體   English   中英

C#奇怪的部門問題

[英]C# Weird division issue

我有一種int和一種uint類型:

int tempA = 0xbc000669;
uint tempB = 0xbc000669;

當我做

tempA /0x2000 ,想向右移動13,它給我0xfffde001

tempB / 0x2000 ,也想向右移動13,它給了我正確的答案: 0x0005e000

有人知道為什么簽名后我得到一個錯誤的答案嗎? 我沒想到分裂會溢出嗎? 謝謝

在聲明中

tempA / 0x2000

編譯器會看到int類型的變量和數字文字值。 由於對int類型的除法需要兩個int類型的操作數,因此值0x2000也會自動轉換為int。 該語句評估為

(int)0xbc000669 / (int)0x2000

這是-1140849047 / 8192等於-139263

十六進制的-139263是FFFDE001(至少在32位值上)

實際上0xbc000669 不能包含在一個int ,更確切的說它代表一個negative integer 我們知道一個int使用第32nd bit作為sign bit 0cbc000669有最顯著半字節為0xb其等於1011 - >的32nd bit1 ,實際是一個負整數。 所以:

int tempA = 0xbc000669;

將使tempA等於-1140849047 ,將此數字右移13個二進制數字將返回獲得的准確結果: 0xfffde001

如果您像這樣將tempB聲明為uint

uint tempB = 0xbc000669;

它可以完全包含在uint因為uint不使用第32nd bit作為符號位。 實際數字是一個positive integer ,其值是3154118249 ,將該值右移13個二進制數將得到准確的結果為0x5e000

從規范中關於整數除法的內容來看:

除法將結果舍入為零,結果的絕對值是最大可能的整數,該整數小於兩個操作數的商的絕對值。 當兩個操作數具有相同的符號時,結果為零或正;而當兩個操作數具有相反的符號時,結果為零或負。

如果我正確地解釋了該文本,則會導致以下情況:在第一個示例中,帶符號的int值設置了符號位; 第二個數字(0x2000)為正,因此結果為零或負。

解釋此問題的最佳方法是顯示位如何工作。 Wikipedia上有關簽名數字表示的文章對此進行了很好的介紹。 您將要閱讀關於二進制補碼的部分。

我認為期望是人們希望-1和1的二進制數相同,但-1的符號位為1。 不是這種情況。 1,例如

0000 0000 0000 0000 0000 0000 0000 0001

-1是

1111 1111 1111 1111 1111 1111 1111 1111

人們直覺上認為-1實際上是-127:

-127 == 1000 0000 0000 0000 0000 0000 0000 0001

現在,讓我們看看您得到的答案。 在有符號除法中,當您向右移動時,實際上實際上是將數字的左側填充1並加1。這就是您在結果中看到的結果。

0xFFFDE001 = 1111 1111 1111 1101 1110 0000 0000 0001
0x0005E000 = 0000 0000 0000 0101 1110 0000 0000 0000

您會注意到,它們都是一樣的,除了最上面的(來自已簽名部門的)左邊有13 1的填充,末尾有1的填充。

對於帶符號整數,要記住的重要一點是,二進制補碼會更改位的順序,因此,除符號位外,-50不具有與+50相同的位模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM