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 509 / 132

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 !
 

Fichier Zip

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

Commentaires et avis

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



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,452 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.