2009-04-20 3 views
8

У меня есть эта строка «1.79769313486232E + 308» и пытаюсь преобразовать ее в числовое значение .NET (double?), Но я получаю следующее исключение. Я использую Convert.ToDouble(). Каков правильный способ сделать это преобразование?Конвертировать "1.79769313486232E + 308" в double без OverflowException?

OverflowException: Значение было либо слишком большим или слишком маленьким для двойной

ответ

11

Проблема, вероятно, связана с тем, что Double.MaxValue был преобразован в строку, и когда строка выводится, не все цифры выводятся, а округляются. Разбор этого значения переполняет двойной.

Использование Double.TryParse, а затем проверка равенства на строке «1.79769313486232E + 308» в случае неудачи и подставляя Double.MaxValue должна быть быстрым обходным путем, если вам нужно сохранить строки, то так оно и есть.

EDIT: Конечно, если вам не нужно держать строку так, как она есть, используйте Round Trip format specifier для создания строки в первую очередь, как Jon describes in his answer.

1

Вы можете попробовать double.Parse() или double.TryParse(), а не Convert.ToDouble(), но я не уверен, что вы получите лучшие результаты. Кстати, строка, которую вы предоставляете, равна double.MaxValue, что является (конечно) максимальным значением, которое может содержаться в двойном, так что, скорее всего, с вашей ошибкой. Численные типы с плавающей запятой являются точными, поэтому я бы предположил, что происходит какое-то округление и выталкивание его за пределы типа.

Вы также можете попробовать тип данных decimal. Тебе может быть повезло.

+1

Или просто использовать double.MaxValue напрямую? Или выполните строковый тест для этой конкретной строки и замените double.MaxValue, так как это, очевидно, особый случай. – gbarry

+1

Десятичное число не будет работать. Decimal.MaxValue codekaizen

-2

Это число слишком велико для двойного, как указано в исключении. Вам нужно будет найти библиотеку большого количества, чтобы справиться с этим для вас, поскольку в библиотеке .Net я не знаю ничего, что обрабатывает очень большие числа.

21

К сожалению, это значение больше double.MaxValue, следовательно исключение.

Как предлагает codekaizen, вы можете жестко запрограммировать тест для строки. Лучшая альтернатива (IMO), если вы один , производя, в первую очередь следует использовать спецификатор формата «r». Затем строка вы производите будет «1.7976931348623157E + 308» вместо этого, который затем разбирает правильно:

string s = double.MaxValue.ToString("r"); 
double d = double.Parse(s); // No exception 

Очевидно, что не поможет, если вы не имеете контроля над данными, - но тогда вы должны понимать, что вы вероятно, потеряют данные уже в этом случае.

+1

+1 для упоминания спецификатора формата "r" в обратном направлении. –

1

Вот что я придумал. Спасибо Jon Skeet и codekaizen.

private double convertToDouble(string str) 
{ 
    double dbl; 

    if (double.TryParse(str, out dbl)) 
     return dbl; 

    if (str == "1.79769313486232E+308") 
     return double.MaxValue; 

    return double.MinValue; 
} 
1

Демонстрирует вопрос и решение:

var s = double.MaxValue.ToString(); 
double d; 
if (!double.TryParse(s, out d)) { 
    d = s.Equals(double.MaxValue) ? double.MaxValue : double.MinValue; 
}