begin process at 2008 08 22 03:57:23
1 229 768 membres
39 nouveaux aujourd'hui
14 267 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

FACTORIELLE


Information sur la source

Catégorie :Maths Niveau : Débutant Date de création : 29/09/2002 Date de mise à jour : 29/09/2002 10:04:04 Vu / téléchargé: 1 296 / 116

Note :
7,67 / 10 - par 3 personnes
7,67 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (3)
Ajouter un commentaire et/ou une note

Description

Ce code sert à calculer rapidement une factorielle complète, cad sans virgule et sans notation scientifique. Pour exemple, 1000! comprend 2568 chiffres.

Source

  • Sub form_load()
  • resultat.Text = ""
  • longueur.Caption = ""
  • progression.Visible = False
  • progression.Value = 0
  • End Sub
  • Sub calfact()
  • Dim reg() As Double
  • Dim n As Double
  • Dim nb_reg As Double
  • Dim i As Double
  • Dim j As Double
  • progression.Visible = True
  • progression.Value = 0
  • longueur.Caption = ""
  • resultat.Text = ""
  • titre = "Saisie."
  • retour_fact:
  • 'Saisie du nombre
  • valeur = InputBox("Valeur de n =", titre, 70)
  • If valeur = "" Then Exit Sub
  • n = Val(valeur)
  • 'Test si n entier
  • If n <> Int(n) Then
  • titre = "n doit être entier !!!"
  • Beep
  • GoTo retour_fact
  • End If
  • 'Calcul et affichage de la longueur de la factorielle (propriété des log => log(a*b)=log(a)+log(b))
  • nb_reg = 0
  • For i = 1 To n
  • nb_reg = nb_reg + log10(i)
  • Next i
  • longueur.Caption = n & " ! comprend " & Int(nb_reg + 1) & " chiffres."
  • DoEvents
  • 'initialisations des registres
  • taille_reg = 10
  • nb_reg = Int(Int(nb_reg + 1) / taille_reg) + 1
  • ReDim reg(nb_reg + 1)
  • 'Mise à 1 du 1er registre sinon n!=0
  • reg(1) = 1
  • 'nb de registre concerné par le calcul=1
  • nr = 1
  • 'Début de calcul
  • For i = 1 To n
  • DoEvents
  • progression.Value = Int(100 * i / n)
  • retenue = 0
  • j = 1
  • While j <= nr
  • reg(j) = reg(j) * i + retenue
  • retenue = Int(reg(j) / 10 ^ (taille_reg))
  • reg(j) = reg(j) - retenue * 10 ^ (taille_reg)
  • 'test de la retenue, si <>0 alors ajout d'un registre pour propagation de la retenue
  • If retenue <> 0 And j = nr Then nr = nr + 1
  • j = j + 1
  • Wend
  • Next i
  • affichage = ""
  • For k = 1 To nb_reg
  • t = Trim(Str(reg(nb_reg + 1 - k)))
  • If (nb_reg + 1 - k) = nb_reg Then GoTo aff
  • If t = "" Or t = "0" Then t = "0000000000"
  • If Len(t) < 10 Then
  • For m = 1 To 10 - Len(t)
  • t = "0" + t
  • Next m
  • End If
  • aff:
  • affichage = affichage + t
  • Next k
  • resultat.Text = affichage
  • progression.Value = 0
  • progression.Visible = False
  • End Sub
  • Function log10(x As Double) As Double
  • log10 = Log(x) / Log(10)
  • End Function
  • Private Sub Command1_Click()
  • calfact
  • End Sub
Sub form_load()
    resultat.Text = ""
    longueur.Caption = ""
    progression.Visible = False
    progression.Value = 0
End Sub
Sub calfact()
    Dim reg() As Double
    Dim n As Double
    Dim nb_reg As Double
    Dim i As Double
    Dim j As Double
    progression.Visible = True
    progression.Value = 0
    longueur.Caption = ""
    resultat.Text = ""
    titre = "Saisie."
retour_fact:
    'Saisie du nombre
    valeur = InputBox("Valeur de n =", titre, 70)
    If valeur = "" Then Exit Sub
    n = Val(valeur)
    'Test si n entier
    If n <> Int(n) Then
        titre = "n doit être entier !!!"
        Beep
        GoTo retour_fact
    End If
    'Calcul et affichage de la longueur de la factorielle (propriété des log => log(a*b)=log(a)+log(b))
    nb_reg = 0
    For i = 1 To n
        nb_reg = nb_reg + log10(i)
    Next i
    longueur.Caption = n & " ! comprend " & Int(nb_reg + 1) & " chiffres."
    DoEvents
    'initialisations des registres
    taille_reg = 10
    nb_reg = Int(Int(nb_reg + 1) / taille_reg) + 1
    ReDim reg(nb_reg + 1)
    'Mise à 1 du 1er registre sinon n!=0
    reg(1) = 1
    'nb de registre concerné par le calcul=1
    nr = 1
    'Début de calcul
    For i = 1 To n
        DoEvents
        progression.Value = Int(100 * i / n)
        retenue = 0
        j = 1
        While j <= nr
            reg(j) = reg(j) * i + retenue
            retenue = Int(reg(j) / 10 ^ (taille_reg))
            reg(j) = reg(j) - retenue * 10 ^ (taille_reg)
            'test de la retenue, si <>0 alors ajout d'un registre pour propagation de la retenue
            If retenue <> 0 And j = nr Then nr = nr + 1
            j = j + 1
        Wend
    Next i
    affichage = ""
    For k = 1 To nb_reg
        t = Trim(Str(reg(nb_reg + 1 - k)))
        If (nb_reg + 1 - k) = nb_reg Then GoTo aff
        If t = "" Or t = "0" Then t = "0000000000"
        If Len(t) < 10 Then
            For m = 1 To 10 - Len(t)
                t = "0" + t
            Next m
        End If
aff:
        affichage = affichage + t
    Next k
    resultat.Text = affichage
    progression.Value = 0
    progression.Visible = False
End Sub
Function log10(x As Double) As Double
    log10 = Log(x) / Log(10)
End Function
Private Sub Command1_Click()
    calfact
End Sub

Conclusion

Je pense que ce code peut être largement optimisé mais je débute alors excusez les erreurs de débutants.
Merci pour vos remarques éventuelles !
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de DARKSIDIOUS le 29/09/2002 10:42:57 administrateur CS

    Mouais, ce n'est pas forcément une méthode ultra rapide, mais on est sûr de trouver le résultat. Cependant, t'as essayé de calculer la factorielle 100000! et voir le temps que ca prend...

    DARK SIDIOUS

  • signaler à un administrateur
    Commentaire de DARKSIDIOUS le 29/09/2002 10:43:48 administrateur CS

    Une autre petite suggestion : évite les GoTo, remplace les par des fonctions où des procédures, c'est plus lisible, et ca fais moins fouilli.

    DARK SIDIOUS

  • signaler à un administrateur
    Commentaire de mehdibou le 29/09/2002 13:13:34

    Si j'ai bien compris le code (ce qui n'est peut être pas le cas), tu calcul en utilisant une chaine de caractère. Ca c du code ! Faudrait généraliser à toutes les opération et en créer un module !

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Août 2008
LMMJVSD
    123
45678910
11121314151617
18192021222324
25262728293031

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Boutique

Boutique de goodies CodeS-SourceS