2011-02-08 5 views
5

Tengo un doble valor que me gustaría convertir a Int32. ¿Cómo puedo verificar antes de convertir si se puede convertir?¿Cómo comprobar si un doble se puede convertir en un Int32?

A veces el valor no está definido y la conversión a Int32 arroja una excepción OverflowException.

ya lo intentó poner a prueba esa manera:

double value = getSomeValue(); 
if (value == Double.NAN) { 
value =0; 
} 
int v = Convert.ToInt32(value); 

Pero esto no cubre todos los casos.

+1

¿Por qué simplemente tratando la conversión y agarrar la excepción no es una opción? –

+5

'NaN'! =' NaN'. – SLaks

+0

un valor nunca puede == NaN (value! = Value es una prueba de NaN válida, valor == NaN - no) – bestsss

Respuesta

8

Quizás esto?

Actualización: I cree la actualización siguiente aborda las causas límite. He probado esto en todos los casos en que pude pensar en verificar la salida contra un método que intenta Convert.ToInt32 directamente y capta la excepción.

static bool TryConvertToInt32(double value, out int result) 
{ 
    const double Min = int.MinValue - 0.5; 
    const double Max = int.MaxValue + 0.5; 

    // Notes: 
    // 1. double.IsNaN is needed for exclusion purposes because NaN compares 
    // false for <, >=, etc. for every value (including itself). 
    // 2. value < Min is correct because -2147483648.5 rounds to int.MinValue. 
    // 3. value >= Max is correct because 2147483648.5 rounds to int.MaxValue + 1. 
    if (double.IsNaN(value) || value < Min || value >= Max) 
    { 
     result = 0; 
     return false; 
    } 

    result = Convert.ToInt32(value); 
    return true; 
} 
+1

Creo que la comprobación de NaN no es necesaria (pero, por supuesto, tampoco está mal) porque NaN no cumple con las desigualdades. – CodesInChaos

+0

ese no es un buen enfoque. simplemente está volviendo a escribir Int.TryParse usted mismo. Int.TryParse ya devuelve 0 y no arroja excepciones. – phillip

+1

@phillip 'TryParse' requiere conversión a' cadena'. Y tiene un comportamiento diferente para dobles con valores no integrales. Entonces esta función es bastante diferente de 'int.TryParse'. – CodesInChaos

0

usted podría intentar algo como esto:

(value>=Int32.MinValue)&&(value<=Int32.MaxValue) 

Esto probablemente falsamente rechazar los valores que están fuera del rango de valores de int pero se redondean en ella. Así que es posible que desee extender el intervalo un poco.

Por ejemplo, Int32.MaxValue+0.1 se rechaza.

¿Cómo quieres tratar dobles no integrales? Este código los acepta y redondea silenciosamente la parte fraccionaria. Las sugerencias basadas en int.TryParse(value.ToString(),...) arrojarán considerar que tales dobles son inválidos.

3

Compruebe si Double.IsNaN y asegurarse de que está entre int.MinValue y int.MaxValue,

+1

Si 'está entre int.MinValue y int.MaxValue', no es NaN por definición. – bestsss

+0

@bestsss: Sí. Estaba tratando de insinuar que '== NaN' está mal. – SLaks

+0

Yo, en serio, no puedo considerar a nadie revisando NaN w/== y exceptuando cualquier resultado, la persona simplemente no entiende cómo funciona NaN. – bestsss

2

Se podría comparar a la gama de un Int32.

if(value <= (double)Int32.MAX_VALUE && value >= (double)Int32.MIN_VALUE) 
    return (Int32)value; 
return 0; 

Por supuesto, si usted quiere devolver el valor Max/Min cuando el doble es demasiado grande, se puede hacer esto:

if(value <= (double)Int32.MAX_VALUE && value >= (double)Int32.MIN_VALUE) 
    return (Int32)value; 
if(value > (double)Int32.MAX_VALUE) 
    return Int32.MAX_VALUE; 
if(value < (double)Int32.MIN_VALUE) 
    return Int32.MIN_VALUE; 
return 0; 
0

A menos que sea absolutamente necesario el rendimiento, lo que acerca del uso de manejo de excepciones ?

+0

Malo por varias razones. Por ejemplo, puede resultar molesto con un depurador adjunto, y también es un mal estilo. – CodesInChaos

+0

Eso es cierto ... Las excepciones deben reservarse para situaciones raras inesperadas. Si el desbordamiento se espera con frecuencia, entonces no es el método correcto. – jdehaan

1

intentar algo como esto:

double d = Double.NaN; 
int i; 
if(Int32.TryParse(d.ToString(), out i)) 
{ 
    Console.WriteLine("Success"); 
    Console.WriteLine(i); 
} else { 
    Console.WriteLine("Fail"); 
} 
+1

1.4 dará como resultado falso pero 1.4 ciertamente puede convertirse a un 'int' (de 1). –

Cuestiones relacionadas