Rem c'est delirant le VB

ortollj

XLDnaute Nouveau
Rem c'est delirant le VB, si je mets les deux lignes ci dessous sur la meme ligne ca ne compile pas !

' comme ca: If P <= N Then combint = ComBin(N, P):mad:

If P <= N Then
combint = ComBin(N, P)
Else
combint = 0
End If
 

ROGER2327

XLDnaute Barbatruc
Re : Rem c'est delirant le VB

Bonjour à tous
Combin ne semble pas être une fonction intégrée de VBA. Il faudrait certainement avoir quelque chose de ce genre :
Code:
[COLOR="DarkSlateGray"][B]Sub toto()
Dim P, N, combint
   If P <= N Then combint = Combin(N, P) Else combint = 0
End Sub

Private Function Combin(N, P)
   Combin = N * P [COLOR="SeaGreen"]'ou tout autre fonction qu'on voudra...[/COLOR]
End Function[/B][/COLOR]
ROGER2327
#2820
 

Roland_M

XLDnaute Barbatruc
Re : Rem c'est delirant le VB

bonsoir à tous, PierreJean, ROGER2327

effectivement PierreJean c'est ce que j'avais pensé au début à un tableau avec des indices erronnés !

c'est après que j'ai réalisé que cela pouvait être une function perso
comme l'avais suggéré, avec humour, notre ami kjin
et comme le démontre ROGER !

mais notre ami ortollj n'a pas l'air de ce manifester !

c'est quelque chose que j'ai du mal à supporter, que l'on ne suive pas de plus près les réponses pouvant être apportées à une question soumise aux forumeurs !
 

ortollj

XLDnaute Nouveau
Re : Rem c'est delirant le VB

un peu de patience messieurs nous somme dimanche, et il n'y a pas que le VB dans la vie !
non il n'y a pas d'erreurs dans les indices puisque cela compile sur 2 lignes
quand je mets une ligne le compilateur me dit else sans if !
c'est etonnant qu'il n'y ait que moi qui ais rencontré ce pb:eek:

Combin(N,P) est une fonction qui avait la pretention de realiser

n!/(n-p)!*p!

la difficulté est qu'il faut ruser (un peu) sinon on ne peut aller tres loing dans les n:cool:
(les P dans mes besoins grandissent assez vite).
pour l'intant elle n'a pas l'air de fonctionner , mais je m'y remets demain:rolleyes:.(j'ais une semaine de vacance:)
voila ce que j'ais ecrit pour Combin

je suis d'accord c'est un peu lourd et pas tres élégant !

Function ComBin(ByVal N As Long, ByVal P As Long) As Long
Dim FirstProduct As Long
Dim SecondProduct As Long
Dim t As Long
Dim Number As Long
FirstProduct = 1
SecondProduct = 1
Rem ActiveCell.Formula = "=FACT(n)"
Number = 2 * N + P
Select Case Number
Case 0
ComBin = 1
Case 1
ComBin = 0
Case 2
ComBin = 1
Case 3
ComBin = 0

Case Else
Rem Debug.WriteLine("Not between 1 and 10, inclusive")
If (P < N) Then

If ((N - P) > P) Then

For t = N - P To N
FirstProduct = FirstProduct * t
Next t
For t = P To 1
SecondProduct = SecondProduct * t
Next t

Else

For t = P To N
FirstProduct = FirstProduct * t
Next t
For t = N - P To 1
SecondProduct = SecondProduct * t
Next t

End If
ComBin = FirstProduct / SecondProduct
Else


ComBin = 0


End If

End Select

End Function
 
Dernière édition:

ROGER2327

XLDnaute Barbatruc
Re : Rem c'est delirant le VB

Re...
Je n'ai pas compris le code proposé.

Pour les "grandes valeurs" de n et p, je propose cette fonction matricielle personnalisée :
Code:
[COLOR="DarkSlateGray"][B]Function ComBinLong(N, P)
[COLOR="Green"]'Fonction [U]matricielle[/U] à appliquer à deux cellules contigües.[/COLOR]
Application.Volatile
Dim i As Long, j As Long, mant As Double, expo As Long
   ComBinLong = Array("", "")
   On Error GoTo E
   N = Int(N)
   P = Int(P)
   P = WorksheetFunction.Max(P, N - P)
   For i = 0 To P - 1
      mant = mant + (Log(N - i) - Log(P - i)) / Log(10)
      If mant >= 1 Then expo = expo + Int(mant): mant = mant - Int(mant)
   Next i
   For j = 0 To N - P - 1
      mant = mant + (Log(N - i - j) - Log(N - P - j)) / Log(10)
      If mant >= 1 Then expo = expo + Int(mant): mant = mant - Int(mant)
   Next j
   ComBinLong = Array(10 ^ mant, expo)
S: On Error GoTo 0
   If Application.Caller.Rows.Count = 2 Then ComBinLong = WorksheetFunction.Transpose(ComBinLong)
Exit Function
E: Resume S
End Function[/B][/COLOR]
Voir la mise en œuvre dans le classeur joint.

Pas sûr que ce soit le problème, mais sait-on jamais ?​
ROGER2327
#2824



Pièce jointe supprimée. Voir le message #11.
 
Dernière édition:

ortollj

XLDnaute Nouveau
Re : Rem c'est delirant le VB

Bonjour
a mon tour roger2327
je n'ai pas encore compris tout a fait ton code (qui a l'air tres elegant, si en plus il fonctionne c'est le paradis !)mais je vais y reflechir.
je pense que tu utilise la formule d'aproximation de Stirling De Moivre ?
log(n!) = n*log(n/e) +1/2*log(n) +1/2*log(2*Pi)
ne perdons pas de vue que le but de conbin etait de réaliser n!/((n-p)!*p!)
 
Dernière édition:

ROGER2327

XLDnaute Barbatruc
Re : Rem c'est delirant le VB

Re...
(...)
je pense que tu utilise la formule d'aproximation de Stirling De Moivre ?
log(n!) = n*log(n/e) +1/2*log(n) +1/2*log(2*Pi)
(...)
Pas du tout... ...mais c'est une voie possible à condition de pousser un peu plus loin le développement limité de log(n!).

Ici, je me contente de calculer
log[n!/(p!.(n-p)!)]
sous la forme
log(n-p+1)-log(1)+log(n-p+2)-log(2)+...+log(n-1)-log(p-1)+log(n)-log(p)
log(x) désigne le logarithme décimal de x.
Pour tenter limiter les effets du cumul des erreurs systématiques de calcul au maximum, j'isole la partie entière dans la variable expo et la partie fractionnaire dans la variable mant.
J'obtiens finalement
log[n!/(p!.(n-p)!)] = expo+mant
soit
n!/(p!.(n-p)!) = 10^mant.10^expo
que je renvoie dans deux cellules contigües sous la forme 10^mant dans la première et expo dans la seconde.

En relisant mon précédent message, je m'aperçois que le code que j'y donne est ridicule. Il fonctionne, mais est inutilement long.
Ferait mieux de dormir à une heure du matin,
plutôt que d'écrire des conneries, celui-là !
Il convient de le remplacer par celui-ci :
Code:
[COLOR="DarkSlateGray"][B]Function ComBinLong(N, P)
[COLOR="SeaGreen"]'Fonction matricielle à appliquer sur deux cellules contigües.[/COLOR]
Application.Volatile
Dim i As Long, mant As Double, expo As Long
   ComBinLong = Array("", "")
   On Error GoTo E
   N = Int(N)
   P = Int(P)
   P = WorksheetFunction.Min(P, N - P)
   If P >= 0 Then
      For i = 1 To P
         mant = mant + (Log(N - P + i) - Log(i)) / Log(10)
         If mant >= 1 Then expo = expo + Int(mant): mant = mant - Int(mant)
      Next i
      ComBinLong = Array(10 ^ mant, expo)
   End If
S: On Error GoTo 0
   If Application.Caller.Rows.Count = 2 Then ComBinLong = WorksheetFunction.Transpose(ComBinLong)
Exit Function
E: Resume S
End Function[/B][/COLOR]
Je joins un fichier rectifié.​
ROGER2327
#2826
 

Pièces jointes

  • Combinaisons_grandes_valeurs_2826.zip
    11.3 KB · Affichages: 17
Dernière édition:

ROGER2327

XLDnaute Barbatruc
Re : Rem c'est delirant le VB

Re...
mais N=6 P=2 Combin=1,5 ?? a la place de 15
Pas du tout !
La formule =ComBinLong(n;p) est matricielle : elle s'utilise sur deux cellules contigües.
Dans le classeur joint à mon précédent envoi, vous pouvez calculer =ComBinLong(6;2) en mettant 6 en A2, 2 en B2. Le résultat apparait en E2 et F2. On y voit 1,5 et 1, c'est-à-dire 1,5 x 10^1 ou encore 15.
Ce dernier calcul apparait en J2.
Mais pour d'aussi petites valeurs de n et p, il suffit d'employer la formule intégrée =COMBIN(n;p) (colonne C).
L'utilisation de la formule logarithmique =ComBinLong(n;p) ne se justifie que pour n > 1029, plus grande valeur admise par la formule intégrée.
Essayez par exemple =COMBIN(1030;515) pour vous en convaincre.​
ROGER2327
#2827
 
Dernière édition:

ortollj

XLDnaute Nouveau
Re : Rem c'est delirant le VB

merci beaucoup ROGER2327
en effet vous avez raison, de plus je ne savais pas qu'il existait une formule integré !
j'ai voulu la creer et sans le faire expres , j'ai pris le meme nom (l'abrégé de combinatoire)
je suis impressioné de l'aisance avec laquelle vous avez resolu cette fonction pour les grand n.
bravo
 

ortollj

XLDnaute Nouveau
Re : Rem c'est delirant le VB

bon ben j'ais quand meme fait ma fonction combin(n,p)
que j'appelles Combina(n,p) et qui fait aussi bien que la Combin(n,p) integré
elles plantent toute les deux a Combin(36,16) depassement de capacité.
Combin(36,15) passe.
Juste pour le plaisir.
je sais je suis a des km de celle de ROGER2327 !

Function ComBina(ByVal N As Long, ByVal P As Long) As Long

Dim num As Double
Dim div As Double
Dim TopBound As Long
Dim LowBound As Long
Dim i As Integer
num = 1
div = 1
If (P = 0 Or P = N Or (N = 0 And P = 0)) Then
ComBina = 1
ElseIf (P < N) Then
TopBound = WorksheetFunction.Max(P, N - P) + 1
LowBound = WorksheetFunction.Min(P, N - P)

For i = TopBound To N
num = num * i
Next i

For i = 1 To LowBound
div = div * i
Next i
If div > 0 Then ComBina = CLng(num / div)
Else
ComBina = 0
End If

End Function
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 299
Messages
2 086 998
Membres
103 429
dernier inscrit
PhilippeH