Почему функции C# round и SQL round дают разные результаты?
Я использую ROUND
функция от C# и SQL, и удивительно, что оба дают разные результаты.
в SQL: ROUND(1250.00, -2)
= 1300
В C# ROUND 1250
С precision = 2
= 1200
кто-нибудь сталкивался с этой ситуацией раньше?
4 ответов
C# использует округление банкира по умолчанию, где, когда вы точно на .5 Марк, оно округляется до ближайшего четного числа, а не округления.
В разделе "примечания" в разделе статьи описывает это поведение. В основном это для уменьшения ошибок округления, когда вы накапливаете много округленных чисел вместе.
Если Вы читаете http://msdn.microsoft.com/en-us/library/wyk4d9cy.aspx, вы увидите, что округление по умолчанию "округляется до четного" (округление банкира), где в качестве SQL Server похоже, используется" стандартное " округление
обновление SQL Server либо делает симметричное арифметическое округление или симметричное округление (исправление) в зависимости от аргументов
Как решить проблему: реализовать пользовательскую процедуру округления: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q196652&ID=KB;EN-US;Q196652
трудная часть в округлении что делать с 5 в десятичной. Они на самом деле ровно на полпути, так что они составляют ничью. Есть хороший бит о ничьи в завершение статьи Википедии. По сути, C# использует округление банкира, которое округляет вниз, когда последняя неокругленная цифра Четна, и вверх, когда она нечетна. Это соответствует стандарту IEEE. SQL вместо этого следует правилу "всегда Раунд 5's up".
используйте параметр в Math.Кругом,MidpointRounding
, чтобы указать способ округления ваших чисел.
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,
}
вы можете использовать это так:
int presicion = 2;
double valueToRound;
Math.Round(valueToRound / Math.Pow(10, precision), MidpointRounding.AwayFromZero)
* Math.Pow(10, precision);