Questo è davvero strano. Mi è stato rintracciare questo errore:Differente comportamento di fusione
Negating the minimum value of a twos complement number is invalid.
... e si è scoperto che era a causa di codice come questo:
var valueFromUser = "470259123000000";
var doubleValue = Convert.ToDouble(valueFromUser, CultureInfo.InvariantCulture);
Math.Abs((int)doubleValue);
In effetti, quando si esegue questo LINQPad:
(int)Convert.ToDouble("470259123000000", CultureInfo.InvariantCulture)
... mi dà:
-2147483648
Tuttavia, un altro sviluppatore qui dice che ottiene qualcosa di completamente diverso (non in LINQPad):
-1141206336
Quando cerco di valutare solo il cast da solo su una costante:
(int)470259123000000.0
... I ottenere un errore di compilazione a causa del bisogno di unchecked
. E questo:
unchecked((int)470259123000000.0)
... viene valutata al -1141206336
come l'altro sviluppatore ha. Quindi ho pensato che forse lo Convert
avesse creato un valore leggermente diverso dalla costante. No, questo restituisce True
:
Convert.ToDouble("470259123000000", CultureInfo.InvariantCulture) == 470259123000000.0
Cosa diavolo sta succedendo qui? Perché la valutazione di queste espressioni apparentemente identiche produce risultati così diversi?
Aggiornamento:
Trovato un suggerimento. La rappresentazione esadecimale di 4.70259123E14
e -1141206336
è:
0x42FABB2BBFA92C00
0xBBFA92C0
quindi credo che uno dei calchi è spingendo i bit direttamente nel int
. Quindi -2147483648
è il mistero più grande.
Interessante. Sembra una differenza tra comportamento di casting controllato e non controllato.Usando l'applicazione "Calcolatrice" ad alta tecnologia (in modalità "Programmatore" ovviamente ;-) Vedo che '-1141206336' corrisponde al troncato (32 lsb) di' 470259123000000'. La versione verificata sembra restituire 'int.MinValue'. Sono sicuro che qualcuno sarà in grado di farlo notare nelle specifiche del linguaggio. – Alex