2011-11-22 25 views
8

Estoy usando ROUND función de C# y SQL, y sorprendentemente ambos están produciendo resultados diferentes.¿Por qué las funciones C# round y SQL round producen diferentes salidas?

En SQL: ROUND(1250.00, -2) = 1,300

En C# ROUND 1250 con redondo y precision = 2 = 1200

Alguien ha encontré con esta situación antes?

+0

qué servidor de base de datos ¿está utilizando ?? – Baz1nga

+0

Se trata de la forma en que los lenguajes son números redondos. Su SQL obviamente redondea hacia ARRIBA y C# redondea hacia ABAJO cuando está justo en el medio. Sugiero intentar usar algo que no sea REDONDO. El techo en SQL redondea, pero sin más información sobre lo que está tratando de hacer es imposible aconsejar sobre qué usar. –

+0

Para aclarar, C# no redondea números; el .NET BCL lo hace. –

Respuesta

7

C# utiliza el redondeo bancario por defecto, donde cuando estás exactamente en la marca de .5, redondea al número par más cercano en lugar de redondear siempre.

La sección de observaciones del msdn article describe este comportamiento. Básicamente se trata de reducir los errores de redondeo cuando se acumulan muchos números redondeados.

0

Utilice el parámetro en Math.Round, MidpointRounding, para especificar la forma de redondear sus números.

public enum MidpointRounding 
{ 
    // When a number is halfway between two others, it is rounded toward 
    // the nearest even number. 
    ToEven = 0, 

    // When a number is halfway between two others, it is rounded toward 
    // the nearest number that is away from zero. 
    AwayFromZero = 1, 
} 

Se puede utilizar de esta manera:

int presicion = 2; 
double valueToRound; 

Math.Round(valueToRound/Math.Pow(10, precision), MidpointRounding.AwayFromZero) 
    * Math.Pow(10, precision); 
+0

He intentado con este parámetro pero sin uso. Aún obteniendo el mismo resultado :( –

1

La parte difícil de redondeo es qué hacer con 5 de en decimal. En realidad, están exactamente a mitad de camino, por lo que constituyen un empate. Hay un poco sobre tie-breaking en el artículo de Roundpedia de Wikipedia. Esencialmente, C# usa el redondeo bancario que redondea hacia abajo cuando el último dígito no redondeado es par y arriba cuando es impar. Esto está en línea con el estándar IEEE. SQL en cambio sigue la regla de "siempre alrededor de 5 arriba".

3

si lee http://msdn.microsoft.com/en-us/library/wyk4d9cy.aspx, verá que el redondeo por defecto es "redondo incluso" (banquero de redondeo) donde como SQL Server parece estar utilizando "estándar" redondeo

actualización de SQL Server o bien no simétrica la aritmética de redondeo simétrico o redondear hacia abajo (Fix) en función de argumentos

cómo resolver el problema: Implementar un procedimiento de redondeo personalizado: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q196652&ID=KB;EN-US;Q196652

+0

El enlace de soporte ya no funciona. Hay una implementación del redondeo de Banker en SQL [aquí] (http://blogs.lessthandot.com/index.php/datamgmt/datadesign/sql -server-rounding-methods /) –

Cuestiones relacionadas