2011-04-21 42 views
6

Se puede hacer la misma pregunta de float ... o de MinValue.¿Es una buena idea comparar double.MaxValue para la igualdad?

Estoy pensando en usarlo como un valor especial. ¿Veo errores debido a la precisión? No espero hacer aritmética con estos números, simplemente configúrelos y listo.

Aclaración: Estoy usando esto para un valor centinela.

¿Es algo que se describe en una especificación de C#?

+0

Sé que esto es una especie de duplicado de los otros, sobre la base de la teoría de la comparación de números de punto flotante . Digo que si el doble es más grande que MaxValue, se desbordará, así que a menos que esté probando para ver si está a punto de desbordarse, entonces creo que será mejor probarlo hasta un límite seguro de precisión. – jcolebrand

+0

¿Puede agregar más detalles a su pregunta? No entiendo lo que quieres comparar. – RoflcoptrException

+1

@Roflcoptr: se agregaron algunos detalles. – GregC

Respuesta

9

Depende de cómo lo use.

Si está usando double.MaxValue como un token o valor centinela que tiene una semántica especial, entonces sí, es solo un patrón de bit con el que compara. Por ejemplo, puede usar double.MaxValue para indicar un valor "no inicializado" o "desconocido". Hay otras formas de hacerlo (por ejemplo, con el nullable double?), pero usar double.MaxValue también es razonable, suponiendo que el valor no se produce naturalmente en su dominio.

Si tiene un valor double arbitrario, y desea ver si es "igual" a double.MaxValue, entonces querrá ver si los números están dentro de un pequeño rango (épsilon) entre sí, ya que algunos la precisión podría haberse perdido al calcular su otro valor double. El problema a tener en cuenta aquí es con valores que van más allá de double.MaxValue, creando una situación de desbordamiento.

+0

¡Buena discusión aquí! – GregC

1

El uso de "valores especiales" es generalmente una mala práctica. Preferiría usar un objeto con algún tipo de código de estado, y luego un doble (/ flotante/lo que sea) que solo se rellena si el estado no es excepcional.

public class CalcNumber 
{ 
    public CalcNumberStatus Status {get; private set;} 
    public double Value {get; private set;} 


    public CalcNumber(double value) 
    { 
     Status = CalcNumberStatus.Normal; 
     Value = value; 
    } 

    public CalcNumber(CalcNumberStatus status) 
    { 
     if(status == CalcNumberStatus.Normal) 
     { 
      throw new Exception("Cannot create a normal CalcNumber without a value"); 
     } 
     Status = status; 
     Value = 0; 
    } 
} 
public enum CalcNumberStatus 
{ 
    Normal, 
    Error 
} 

Incluso podría hacer una sobrecarga de operador elegante para facilitar la conversión y la aritmética si es necesario.

En cuanto a los problemas de precisión, ya que parece que no está planeando hacer operaciones aritméticas en este número, por lo que no debería encontrarse con problemas de precisión que impidan que funcione la verificación de igualdad.

+0

Tengo algunas (discutible) limitaciones autoimpuestas dentro de Codegen que la compañía usa. Tengo que pegarme al tipo primitivo aquí. – GregC

+1

@GregC: Mis simpatías. – StriplingWarrior

2

Si compara double.MaxValue a double.MaxValue, sí, serán lo mismo. La representación binaria es idéntica, no habrá ningún problema. Si, por el contrario, se intenta algo como:

double myDouble = (double.MaxValue - 3.1415)/2; 
if((myDouble * 2) + 3.1415 == double.MaxValue) 
{ 
    ... 
} 

entonces sí es probable que comience a ver los problemas de precisión extraños pop-up.

Las siguientes son constantes especiales que no se pueden comparar entre sí. Todo lo demás es juego limpio.

  • NaN
  • NegativeInfinity
  • PositiveInfinity
+0

He leído en algún lado que es una mala idea comparar el infinito (ya sea positivo o negativo) con ==. Es por eso que el doble tiene funciones de utilidad para aquellos. –

+0

Ah sí, me olvidé de ellos. Lo mismo aplica para ellos como NaN. –

+0

Lo actualicé para reflejar las constantes que requieren pruebas especiales. –

0

no creo que debería ser un problema. No tengo una explicación técnica, pero he usado MaxValue o MinValue para hacer comparaciones muchas veces y nunca ha sido un problema.

1

Si desea un valor "especial", mi sugerencia sería utilizar Nullable lugar:

double? val = ...; 

if(val.HasValue) 
    // do something with val.Value 
+0

He utilizado null, NaN, Inf positivo y Negativo. – GregC

+3

@GregC: Uhoh. Tiempo para números complejos, mi amigo – sehe

+0

@GregC Algo definitivamente está mal con su diseño. ¿Has oído hablar de excepciones? –

Cuestiones relacionadas