1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

VBA (Factorial acima de 170, com .txt ??)

Discussão em 'Programação' iniciada por jorge17, 13 de Junho de 2012. (Respostas: 4; Visualizações: 762)

  1. jorge17

    jorge17 Power Member

    Boas, é o seguinte, fiz em vba um programita simples(mas k me deu mt trabalho visto que sou um 0 a eskerda lol) que calcula o factorial de um numero posto pelo utilizador e dá a resposta na textbox2

    ora portanto o meu problema como sabem, como double o factorial o e calculado ate ao 170, depois da overflow.
    pelo que eu percebi a soluçao, ir buscar a resposta a um txt de fora.
    Alguem me consegue explicar o que preciso entao para calcular o factorial de numeros maiores por exemplo 2000
    thanks

    ps: o meu codigo e este

    Código:
    Private Sub CommandButton1_Click()
    Dim number As Double
    Dim fact As Double
    
    If number = 0 Then
        TextBox2.Text = 1
    End If
        fact = 1
            For number = 1 To Val(TextBox1.Text)
                fact = fact * number
            Next number
                TextBox2.Text = fact
    End Sub
     
  2. cyberadelino

    cyberadelino Power Member

    para valores que excedam os 32 bits do inteiro as contas tem que ser feitas digito a digito como na escola primária (ou possivelmente com vários mas torna-se mais complicado) e os digitos vão sendo armazenado numa string

    vê por exemplo aqui
    http://visualbasic.about.com/b/2007/12/15/large-number-calculations.htm
    há bastante informação no google se procurares
    isto faz-te as multiplicações depois tens de adaptar o factorial para chamar esta função de multiplicar em vez de multiplicar directamente
     
  3. rocksparty

    rocksparty Power Member

    No
    Código:
    If [B]number[/B] = 0 Then..
    Não deveria ser
    Código:
    If [B]Val(TextBox1.Text)[/B] = 0 Then..
    ?
     
  4. jorge17

    jorge17 Power Member

    ok vou dar uma olhada a isso no fim do jogo thanks
     
  5. fmf1966

    fmf1966 Power Member

    Algum tempo atrás criei um modulo VBA para fazer adições e multiplicações com numeros inteiro bem longos (teoricamente até 65536 digitos).

    Deixo aqui, já com um procedimento para listar os factoriais até 1000.

    Código:
    Option Explicit
    
    Private Sub ListaFactoriais()
        Dim A As String, X As String
        
        A = 1
        X = 1
        Do Until Val(A) >= 1000
            X = MultiplicarLongos(A, X)
            Debug.Print A & "!= " & X
            A = AdicionarLongos(A, "1")
        Loop
    End Sub  
      
    
    Public Function AdicionarLongos(Num1 As String, Num2 As String) As String
        Dim P1() As Long, P2() As Long
        Dim I As Long, J As Long, Q As Long
        
        If Not NumeroValido(Num1) Or Not NumeroValido(Num2) Then
            AdicionarLongos = "#"
            Exit Function
        End If
        
        Texto2Matriz P1, Num1
        Texto2Matriz P2, Num2
        
        I = UBound(P1) + 1
        J = UBound(P2) + 1
        If J < I Then J = I
        ReDim Preserve P1(J)
        ReDim Preserve P2(J)
        
        For I = 0 To J - 1
            Q = P1(I) + P2(I) + Q
            P1(I) = Q Mod 1000
            Q = Q \ 1000
        Next I
        If Q Then P1(I) = Q
        
        Matriz2Texto P1, AdicionarLongos
    End Function
         
    Public Function MultiplicarLongos(Num1 As String, Num2 As String) As String
        Dim P1() As Long, P2() As Long, P3() As Long
        Dim S As String, X() As String
        Dim I As Long, J As Long, K As Long, Q As Long
        
        If Not NumeroValido(Num1) Or Not NumeroValido(Num2) Then
            MultiplicarLongos = "#"
            Exit Function
        End If
        
        Texto2Matriz P1, Num1
        Texto2Matriz P2, Num2
        ReDim X(UBound(P1))
        
        For I = 0 To UBound(P1)
            ReDim P3(1 + UBound(P1) + UBound(P2))
            Q = 0
            For J = 0 To UBound(P2)
                Q = P1(I) * P2(J) + Q
                P3(I + J) = Q Mod 1000
                Q = Q \ 1000
            Next J
            If Q Then P3(I + J) = Q
            Matriz2Texto P3, X(I)
        Next I
        
        S = X(0)
        For I = 1 To UBound(P1)
            S = AdicionarLongos(S, X(I))
        Next I
        
        MultiplicarLongos = S
    End Function
         
    Private Sub TrimZero(ByRef Texto As String)
        Dim I As Long
        
        I = 1
        Do Until Val(Mid(Texto, I, 1)) > 0
            If I >= Len(Texto) Then Exit Do
            I = I + 1
        Loop
        Texto = Mid(Texto, I)
    End Sub
    Private Function NumeroValido(ByVal Texto As String) As Boolean
        Dim I As Long
        
        For I = 1 To Len(Texto)
            If Not IsNumeric(Mid(Texto, I, 1)) Then
                NumeroValido = False
                Exit Function
            End If
        Next I
        NumeroValido = True
    End Function
    
    
       
    Private Sub Matriz2Texto(ByRef Matriz() As Long, ByRef Texto As String)
        Dim I As Long
        
        Texto = ""
        For I = 0 To UBound(Matriz)
            Texto = Format(Matriz(I), "000") & Texto
        Next I
        TrimZero Texto
    End Sub
    
        
    Private Sub Texto2Matriz(ByRef Matriz() As Long, ByRef Texto As String)
        Dim I As Long, J As Long, N As Long
        
        TrimZero Texto
        N = Len(Texto)
        If Not N Then N = N \ 3
        ReDim Matriz(N)
        If Len(Texto) < 1 Then Exit Sub
        
        I = Len(Texto) - 2
        J = 0
        
        Do While I > 0
            Matriz(J) = Val(Mid(Texto, I, 3))
            J = J + 1
            I = I - 3
        Loop
        If I > -2 Then Matriz(J) = Left(Texto, I + 2)
    End Sub
    Por curiosidade o Factorial de 170 tem 307 digitos, e o factorial de 2000 tem 5733 digitos e demorou 13 segundos a calcular no VBA do Excel 2010.
     
    Última edição: 14 de Junho de 2012

Partilhar esta Página