2010-09-01 9 views
46

In C# vedo che-1 * int.MinValue == int.MinValue ?? è un insetto?

-1 * int.MinValue == int.MinValue 

È questo un bug? Mi ha davvero rovinato quando stavo cercando di implementare un albero di ricerca. Ho finito per utilizzare (int.MinValue + 1) in modo da poterlo negare correttamente.

+5

+1 Domanda molto interessante e divertente: D – Jonathan

+1

Questa è una di quelle cose che davvero non capisco, perché C# è deselezionato per impostazione predefinita? – Aelphaeis

risposta

57

Questo non è un bug.

int.MinValue * -1 è 1 superiore a int.MaxValue può contenere. Quindi, il numero torna indietro a int.MinValue.

Ciò è causato principalmente da un overflow di numeri interi.

Int32.MinValue:

Il valore di questa costante è -2,147,483,648

Int32.MaxValue:

Il valore di questa costante è 2,147,483,647

Quindi, -2,147,483,648 * -1 = 2,147,483,648 che è 1 superiore a Int32.MaxValue.

+1

la matematica integer è sooo coool! ;) –

+1

@ Mark, in questo caso, penso che non sia bello. È confuso. – jjnguy

+0

Dipende da come lo guardi. Da una prospettiva bit a bit con '-x: = ~ x + 1' e' Int32.MinValue' è "1000 0000 0000 0000 0000 0000 0000 0000' in realtà è abbastanza plausibile. E il '32' in 'Int32' punta esattamente a quella direzione :) – back2dos

9

Non è un bug, è un overflow.

Nella rappresentazione two's complement, lo spazio dei numeri rappresentabili non è simmetrico. L'opposto del più piccolo numero intero non può essere rappresentato. Il calcolo è eccessivo e ti restituisce lo stesso numero.

+7

per meno di un secondo, pensavo che avresti detto Non è un bug, è una caratteristica. : D – Jonathan

8
int i = -1 * int.MinValue; 

Questo non ha nemmeno compilare a meno che non si disattiva il controllo:

error CS0220: The operation overflows at compile time in checked mode 
+0

Volevo solo notare che la modalità selezionata è apparentemente disabilitata di default.http: //msdn.microsoft.com/en-us/library/h25wtyxf.aspx – Aelphaeis

2

No, non è un bug. È la natura dei due complementi aritmetici interi.

Ad esempio, prendiamo un valore di byte con segno che va tra -128 e 127.

127(0x7f)+1 = 128(0x80). Tuttavia, 0x80 è in effetti la rappresentazione binaria di -128.

Così, ad un byte, 128(0x80) = -128(0x80)

Così -128(0x80) * -1 = 128(0x80) = -128(0x80)

2

Metti una regione controllato su di esso e vedere il "bug" evolvono in un'eccezione. Oppure prova VB.NET (che, per quanto ricordo, è selezionato di default a differenza di C#).

+0

+1 per menzionare lo stato selezionato. – Aelphaeis

Problemi correlati