2009-05-19 17 views
6

Actualmente estoy leyendo Code Complete por Steve McConnell, específicamente página 295 en números de punto flotante.Incrementos de impresión de 0.1 en C#

cuando me encontré con el siguiente código:

 double nominal = 1.0; 
     double sum = 0.0; 

     for (int i = 0; i < 10; i++) 
     { 
      sum += 0.1; 
      Console.WriteLine("sum: " + sum.ToString()); 
     } 

     if (equals(nominal,sum)) 
     { 
      Console.WriteLine("Numbers are the same"); 
     } 
     else 
     { 
      Console.WriteLine("Numbers are different"); 
     } 

Tengo una impresión de 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1,0 números son diferentes

¿Cómo es que no lo hice? ¿obtener la salida que se supone que va a pasar? es decir: 0,1 0,2 0.30000000000000004 0,4 0,5 0,6 0,7 0.79999999999999999 0.89999999999999999 0.99999999999999999 números son diferentes

son los números de C# de redondeo cuando lo haga una conversión implícita de doble a cadena? Creo que sí, porque cuando depuro la aplicación y paso por el ciclo for, puedo ver los números decimales que no se terminan. ¿Qué piensas? ¿Estoy en lo correcto o incorrecto?

Respuesta

12

double.ToString() utiliza el formato general que tiene como valor predeterminado 15 decimales si no se especifica la precisión. Así que hace un pequeño redondeo y es por eso que estás viendo lo que estás viendo. Por ejemplo, 0.89999999999999999 que especificó en su pregunta es 17 decimales. En realidad, puede ver el número completo haciendo sum.ToString("g17").

Puede encontrar Cadenas de formato estándar numéricas .NET de su precisión y por defecto aquí: http://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx

+0

Ahh gracias. Debería haber sido muy preciso con las salidas que te he dado. Cuando di números decimales largos como 0.79999999999999999, no estaba prestando atención a la cantidad de dígitos que estaba usando. – burnt1ce

2

Es decir, en el comportamiento por defecto ToString. Si nos fijamos en suma en el depurador obtiene este, que muestra el valor sin el enrutamiento a través ToString:

0.0 
0.1 
0.2 
0.30000000000000004 
0.4 
0.5 
0.6 
0.7 
0.79999999999999993 
0.89999999999999991 

lo que indica que el comportamiento subyacente es como era de esperar.

hth

2

La respuesta corta es: Está en coma flotante, así que no contar con cualquier cosa menos que sea a la derecha (para los valores adecuados de "derecha")! El largo que responde es comprender cómo funciona el punto flotante y cómo las personas trabajan con punto flotante. IIRC GNU printf (y otros supondrían) caso especial "realmente muy cerca de un buen número de base 10".