Я бы сказал, что это невозможно, чтобы каждая результирующая строка была независимой. Используйте язык программирования для получения этих значений
Я думаю, что вам лучше всего сделать следующее:
checked
{
try
{
int bar = (int)foo;
}
catch (OverflowException)
{
...
}
}
Из Таблицы явных числовых преобразований
При преобразовании из двойного или плавающего значения в целочисленный тип, значение усекается. Если полученное интегральное значение выходит за пределы диапазон целевого значения, результат зависит от переполнения проверка контекста. В проверенном контексте возникает исключение OverflowException. брошено, а в непроверенном контексте результатом является неуказанный значение типа назначения.
Примечание. Вариант 2 также вызывает OverflowException
, когда это необходимо.
Я предпочитаю вариант 2.
Для подтверждения того, что все получилось, нужно проверить исключения, так же, как вы проверяете 'parsed' в варианте 1:
try
{
bar = Convert.ToInt32(foo);
}
catch(OverflowException)
{
// no can do!
{
Если вы преобразовывали строку и т.д. вместо двойки, вы можете получить 'FormatException'.
Edit
Изначально я сказал, что вариант 2 не лучше варианта 1, на что @0xA3 указал, что это неверно. Вариант 1 хуже, потому что он конвертирует в строку перед разбором в целое число, что означает, что он менее эффективен. Вы также не получите OverflowException, если double выходит за пределы целочисленного диапазона (что вам может быть нужно, а может и не быть) - хотя 'parsed' в этом случае будет False.
Вариант 3a, не использующий исключения, всегда возвращает значение:
Int32 Convert(Double d)
{
if (d <= (double)Int32.MinValue)
return Int32.MinValue;
else if (d >= (double)Int32.MaxValue)
return Int32.MaxValue;
else
return (Int32)d;
}
Я всегда использую класс Convert, он мне очень элегантен, удобен, и вы можете перехватывать определенные исключения, определенные в VS intellisense.
Опции (1) и (2) делают, по сути, одно и то же. Вариант (1) дает вам блок if (разобранный)
, тогда как вариант (2) выдает ошибку для любого double
, который не может быть представлен как int
.
Вариант (3) по сути такой же, как вариант (2), за исключением того, что он имеет дополнительную проверку MinValue
/ MaxValue
, которой нет у других.
В итоге: эти три части кода делают разные вещи. Вариант (3) выглядит наиболее надежным, поскольку в нем есть дополнительная проверка диапазона.
Правка: Если подумать, воспользуйтесь уловкой @Ani checked
- вы получите проверку диапазона бесплатно.
Я понимаю, что это не совсем то, о чем просил OP, но эта информация может оказаться полезной.
Вот сравнение (из http://www.dotnetspider.com/resources/1812-Difference-among-Int-Parse-Convert-ToInt.aspx )
string s1 = "1234";
string s2 = "1234.65";
string s3 = null;
string s4 = "12345678901234567890123456789012345678901234567890";
int result;
bool success;
result = Int32.Parse(s1); // 1234
result = Int32.Parse(s2); // FormatException
result = Int32.Parse(s3); // ArgumentNullException
result = Int32.Parse(s4); // OverflowException
result = Convert.ToInt32(s1); // 1234
result = Convert.ToInt32(s2); // FormatException
result = Convert.ToInt32(s3); // 0
result = Convert.ToInt32(s4); // OverflowException
success = Int32.TryParse(s1, out result); // 1234
success = Int32.TryParse(s2, out result); // 0
success = Int32.TryParse(s3, out result); // 0
success = Int32.TryParse(s4, out result); // 0
Я бы использовал второй вариант. Коротко, чисто, и все работает.
Вы также можете изучить класс BigInteger в .Net4, и вам не придется проверять переполнение.
double foo = 1;
BigInteger bigint = new BigInteger(foo);
Если вам действительно нужно это выяснить если что-то пошло не так, воспользуйтесь обычным приведением и проверьте результат.
int ToInt(double foo)
{
int result = (int)foo;
if (foo != result)
throw new ArgumentException()
return result;
}
Это позволит избежать недопустимых преобразований. Если можно округлить до ближайшего целого числа, используйте Math.Round
и проверьте, находится ли результат в пределах 0,5. Это гарантирует, что ваш метод не получит NaN или бесконечности.