Столкнулись на работе с интересным поведением Convert.ToInt32. Почти всегда работает предсказуемо, кроме граничных случаев (оканчивающихся на ".5").
Обзор документации дал вполне точное (но при этом достаточно странное) объяснение:
Т.е. неискушенные умы могут подумать, что это ошибка. Вот код соответствующий «волшебному» методу:
Можно заметить, что во внутреннем условии есть проверка на четность, которая и вносит «магические» коррективы. Для чего это необходимо, для меня осталось загадкой.
Покопавшись в интернете есть статьи, в которых столкнулись с похожей проблемой, где, как вариант, предлагают использовать операции приведения. Мы же решили сделать свою реализацию, убрав условия проверки:
В комментариях можно оставить предположения, для чего добавлена «магия» в этот, с виду предсказуемый, метод.
Обзор документации дал вполне точное (но при этом достаточно странное) объяснение:
If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.
Т.е. неискушенные умы могут подумать, что это ошибка. Вот код соответствующий «волшебному» методу:
public static int ToInt32(double value)
{
if (value >= 0.0)
{
if (value < 2147483647.5)
{
int num1 = (int) value;
double num2 = value - (double) num1;
if (num2 > 0.5 || num2 == 0.5 && <b>(num1 & 1) != 0</b>)
++num1;
return num1;
}
}
else if (value >= -2147483648.5)
{
int num1 = (int) value;
double num2 = value - (double) num1;
if (num2 < -0.5 || num2 == -0.5 <b>&& (num1 & 1) != 0</b>)
--num1;
return num1;
}
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}
Можно заметить, что во внутреннем условии есть проверка на четность, которая и вносит «магические» коррективы. Для чего это необходимо, для меня осталось загадкой.
Покопавшись в интернете есть статьи, в которых столкнулись с похожей проблемой, где, как вариант, предлагают использовать операции приведения. Мы же решили сделать свою реализацию, убрав условия проверки:
public static int ToInt32(double value)
{
if (value >= 0.0)
{
if (value < 2147483647.5)
{
int num1 = (int) value;
double num2 = value - (double) num1;
if (num2 > 0.5 || num2 == 0.5)
++num1;
return num1;
}
}
else if (value >= -2147483648.5)
{
int num1 = (int) value;
double num2 = value - (double) num1;
if (num2 < -0.5 || num2 == -0.5)
--num1;
return num1;
}
throw new OurOverflowException('Int32 overflow error message');
}
В комментариях можно оставить предположения, для чего добавлена «магия» в этот, с виду предсказуемый, метод.