Исключение переполнения? - PullRequest
0 голосов
/ 30 марта 2011

У меня есть следующий код для поиска факториалов:

Private Shared Function Factorial(ByVal Number As Long) As Long
        If Number = 0 Then
            Return 1
        Else
            Return Number * Factorial(Number - 1)
        End If
End Function

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

Мне нужно работать со стартовыми номерами, такими как 30-60.

Есть идеи? Я думал, что изменение типа значения на LONG предотвратит эту проблему.

Это VB.net только для справки.

Ответы [ 3 ]

4 голосов
/ 30 марта 2011

Факториалы становятся очень большими, очень быстро. Наибольшее число, которое поместится в Long, составляет около 9 × 10 ^ 18. Факториал (30) составляет около 2,7 × 10 ^ 32.

Если вы используете .Net 4, есть встроенный класс BigInteger, который вы можете использовать, который будет содержать произвольно большие числа.

Если вы не используете .Net 4, вам нужно найти и загрузить библиотеку BigInteger, например, intx .

2 голосов
/ 05 апреля 2012

Вы получаете исключение переполнения только для целочисленных и длинных типов. Чтобы избежать этого, вы можете использовать System.Double или System.Numerics.BigInteger (или BigDecimal, я думаю).

Например, если вы запускаете 3 разные версии факториала: 1 с длинной, 1 с двойной и 1 с biginteger, как следует, с диапазоном значений от 5 до 50 на 5:

    'Long Factorial   
    Public Function FactorialInt64(ByVal n As Integer) As Int64  
        If n = 1 Then  
            Return 1  
        Else  
            Return n * FactorialInt64(n - 1)  
        End If  
    End Function  
    ' Double Factorial   
    Public Function FactorialDouble(ByVal n As Integer) As Double  
        If n = 1 Then  
            Return 1  
        Else  
            Return n * FactorialDouble(n - 1)  
        End If  
    End Function  
    ' BigInteger Factorial   
    Public Function FactorialBigInteger(ByVal n As Integer) As BigInteger  
        If n = 1 Then  
            Return 1  
        Else  
            Return n * FactorialBigInteger(n - 1)  
        End If  
    End Function  

Вы получите такой результат:

Factorial execution results

Вы можете найти полный исходный код в моем блоге: Факториал и Фибоначчи в VB.NET

1 голос
/ 30 марта 2011

Существует big int Library для .NET , которая решит вашу проблему. Он может манипулировать очень большим числом (ограничено только вашей системной памятью).

Вот ссылка: http://www.emilstefanov.net/Projects/GnuMpDotNet/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...