IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

Opérations sur les grands nombres dans Q


Sujet :

Contribuez

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Points : 8
    Points
    8
    Par défaut Opérations sur les grands nombres dans Q
    Bonjour,
    une petite fonction pour ceux qui aimeraient additionner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    21599680283161715807847052066540433422883515772119658063766498972503219104278316186542706552263614678844605521205471865945806520838603391933189946547621953603163789045147079719349493433360218263689302235202664706161893962580201172846238976101277970849319269574650368333475
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    34949016844286609244702569396854666560394034993558941124290697993541159157408353213414067918381143829834632521368500895227875598278931979619120652866805525601567068468443815905896034842579691540576942087418297880155633577640852959781937445848583239709367624451704319243301
    avec le résultat sous la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    56548697127448325052549621463395099983277550765678599188057196966044378261686669399956774470644758508679238042573972761173682119117535371552310599414427479204730857513590895625245528275939909804266244322620962586317527540221054132628176421949861210558686894026354687576776
    et non
    5,6549E+271
    Le résultat est un nombre sous forme de texte. En entrée la fonction accepte tout nombre entier sous forme de texte et tout entier < 10^15.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    Function SommeInf(NumberArg1, NumberArg2) As String
    Dim L1 As Long
    Dim L2 As Long
    Dim Mx As Long
    Dim v1 As Long
    Dim v2 As Long
    Dim v3 As Long
    Dim i As Long
    Dim S As String
    Dim R As Long
        L1 = Len(NumberArg1)
        L2 = Len(NumberArg2)
        S = ""
        R = 0
        If L1 >= L2 Then Mx = L1
        If L2 > L1 Then Mx = L2
        For i = 1 To Mx
        v1 = Left(Right(NumberArg1, i), 1)
        If i > L1 Then v1 = 0
        v2 = Left(Right(NumberArg2, i), 1)
        If i > L2 Then v2 = 0
        v3 = v1 + v2 + R
        If v3 < 10 Then R = 0
        If v3 > 9 Then v3 = v3 - 10: R = 1
        S = v3 & S
        Next i
        If R = 1 Then SommeInf = R & S
        If R = 0 Then SommeInf = S
    End Function

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 84
    Points
    84
    Par défaut Opérations sur les grands nombres dans Q
    Annule et remplace le post précédent.

    Ecrit avec Excel 2007 mais probablement compatible avec les versions précédentes.

    Une copie d'écran pour avoir une bonne idée des fonctions :



    Les fonctions pour l'utilisateur :
    SommQ(x As String, y As String) As String: x+y
    SousQ(x As String, y As String) As String: x-y
    ProdQ(x As String, y As String) As String: x*ys
    Function DiviQ(x As String, y As String) As String: x/y

    Ces fonctions imbricables sont à utiliser avec parcimonie, je conseille procéder par tests de difficultés croissants, de sauvegarder souvent son travail, il est très facile de lancer Excel dans des calculs considérables...

    1ère contrainte : le résultat doit être formaté pour pouvoir être correctement interprété dans une nouvelle opération
    Conventions d'écriture unique du résultat:
    Soit Res le résultat affiché :
    Si Res < 0:
    Res=_(a+b/c)
    Si b=0, Res=_a
    Si Res >= 0:
    Res=a+b/c
    Si b=0, Res=a
    avec a entier égal à Int(Abs(Res))
    et b,c entiers non nuls et b<c
    exemples:
    22/7 sera affiché: 3+1/7
    1+8/6 sera affiché: 2+1/3
    -13/7 sera affiché: _(1+6/13)
    2-7/3 sera affiché: _(0+1/3)
    -2+260/10 sera affiché: 24
    En d'autres termes :
    la partie fractionnaire est toujours positive et < 1
    Les symboles utilisés (_,+,/,(,)) sont des constantes publiques et donc modifiables. Je déconseille l'utilisation du - comme symbole négatif.

    2ème contrainte : pour la simplification des fractions l'option d'utiliser une table des nombres premiers a été choisie
    Une feuille nommée "1er" et comportant cette liste en colonne 1 est nécessaire aux fonctions.
    Le paramètre "1er" est aussi une constante publique donc modifiable ainsi que le numéro de la colonne (cCol)
    La macro Premiers 1 construit cette liste sur la feuille active. La colonne 1 doit être vide au départ. Si elle ne l'est pas la macro considère qu'elle doit continuer une liste commencée en considérant la valeur de la dernière cellule écrite comme étant celle du dernier premier trouvé .
    A titre d'exemple la liste que j'utilise contient les 952137 premiers premiers (ahem..), de 1 à 14692813 et a été générée en une nuit. Le csv pèse 8,36 Mo
    En conséquence on ne peut être certain de l'irréductibilité d'une fraction affichée que si son diviseur est inférieur au carré du dernier nombre premier de la liste.
    Il peut être plus pratique de conserver la liste dans un csv à importer ou à copier à chaque ouverture du classeur.
    A cet effet la macro XlsToCsv transforme en csv le tableau de la feuille active.
    Pour un résultat correct la feuille ne doit contenir que le tableau, celui ci doit commencer en A1 et la dernière cellule de la colonne 1 ainsi que la dernière cellule de la ligne 1 doivent être non vides.

    Construction de la liste des nombres premiers (incluant 1) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    Sub Premiers1()
    'construit les 1er en colonne1
     Dim vTst As Long
     Dim x As Long
     Dim j As Long
     Dim d, f, t
     Dim vRw As Long
     Dim vLLV As Long
     Dim vLLR As Long
        x = Application.InputBox("Limite supérieure?", Type:=1)
        vLLR = Cells(Rows.Count, 1).End(xlUp).Row
        vLLV = Cells(vLLR, 1)
        If x <= vLLV Then
            MsgBox "La Colonne 1 va déjà au delà de la limite demandée"
            Exit Sub
        End If
        'Application.ScreenUpdating = False
        If vLLR = 1 Then
            Cells(1, 1) = 1
            Cells(2, 1) = 2
            vTst = 2
            vRw = 2
        Else
            vTst = vLLV
            vRw = vLLR
        End If
    Line0:
        vRw = vRw + 1
    Line1:
        vTst = vTst + 1
        If vTst = x + 1 Then GoTo Line2
        For j = 2 To vRw - 1
            If vTst Mod Cells(j, 1) = 0 Then GoTo Line1
            If vTst / Cells(j, 1) < Cells(j, 1) Then GoTo Line3
        Next j
    Line3:
        Cells(vRw, 1) = vTst
        GoTo Line0
    Line2:
        'Application.ScreenUpdating = True
    End Sub
    Création d'un csv à partir d'une feuille ne contenant qu'un tableau commençant en A1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Sub XlsToCsv()
    Dim vStr As String
    Dim i As Long
    Dim j As Integer
    Dim vLRw As Long
    Dim vICl As Integer
    Dim vSFN As String
    Dim Rep As Byte
        vSFN = Application.GetSaveAsFilename(ActiveSheet.Name & ".csv", "Csv Files (*.csv), *.csv")
        vLRw = Cells(Rows.Count, 1).End(xlUp).Row
        vICl = Cells(1, Columns.Count).End(xlToLeft).Column
        ChDir ThisWorkbook.Path
        Rep = MsgBox("Le fichier comportera " & vLRw & " lignes et " & vICl & " colonnes. Accepter ?", 1)
        If Rep = 2 Then Exit Sub
        Open vSFN For Output As #1
        For i = 1 To vLRw
        vStr = ""
            For j = 1 To vICl
                vStr = vStr & Cells(i, j).Value
                vStr = vStr & ";"
            Next j
            vStr = Left(vStr, Len(vStr) - 1)
            Print #1, vStr
        Next i
        Close #1
    End Sub
    Les variables publiques et les 4 fonctions destinées à l'utilisateur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    Option Explicit
     
    Public Const cM As String = "_"
    Public Const cP As String = "+"
    Public Const cD As String = "/"
    Public Const cOp As String = "("
    Public Const cFp As String = ")"
    Public Const cSN1 As String = "1er"
    Public Const cCol As Byte = 1
    Public Const ceD0 As String = "Div/0"
     
    Function SommQ(x As String, y As String) As String
    'fonction addition de Q vers Q
    Dim vSNmx As String
    Dim vSNmy As String
    Dim vSDv As String
    Dim vSSNm As String
    Dim vBSNm As Boolean
    Dim vSSInt As String
    Dim vBSInt As Boolean
    Dim z1 As String
    Dim z2 As String
    Dim v1 As Boolean
    Dim v2 As Boolean
    Dim v3 As String
    Dim v4 As String
    Dim v5 As String
    Dim v6 As String
    Dim v7 As String
    Dim v8 As String
        'identification des paramètres
        v5 = IdenQ(x, 2)
        v6 = IdenQ(y, 2)
        v7 = IdenQ(x, 3)
        v8 = IdenQ(y, 3)
        'Partie numérateur de x pour le multiplicateur commun de x,y
        vSNmx = ProdN(v5, v8)
        'Partie numérateur de y pour le multiplicateur commun de x,y
        vSNmy = ProdN(v7, v6)
        'Multiplicateur commun de x,y
        vSDv = ProdN(v7, v8)
        'identification des paramètres
        v1 = SignQ(x)
        v2 = SignQ(y)
        v3 = IdenQ(x, 1)
        v4 = IdenQ(y, 1)
        'Opérations Intermédiaires
        If v1 = v2 Then
            vSSNm = SommN(vSNmx, vSNmy)
            vBSNm = v1
            vSSInt = SommN(v3, v4)
            vBSInt = v1
            If XseYN(vSSNm, vSDv) = True Then
                vSSNm = DiffN(vSSNm, vSDv)
                vSSInt = SommN(vSSInt, "1")
            End If
        Else
            vSSNm = DiffN(vSNmx, vSNmy)
            If XseYN(vSNmx, vSNmy) = True Then
                vBSNm = v1
            Else
                vBSNm = v2
            End If
            vSSInt = DiffN(v3, v4)
            If XseYN(v3, v4) = True Then
                vBSInt = v1
            Else
                vBSInt = v2
            End If
        End If
        'Résultat
        If vSSNm = "0" Then
            If vBSInt = True Then
                SommQ = vSSInt
            Else
                If vSSInt = 0 Then
                    SommQ = "0"
                Else
                    SommQ = cM & vSSInt
                End If
            End If
        Else
            z1 = vSSNm
            z2 = vSDv
            vSSNm = SimpN(z1, z2, 1)
            vSDv = SimpN(z1, z2, 2)
            If vSSInt = "0" Then
                If vBSNm = True Then
                    SommQ = "0" & cP & vSSNm & cD & vSDv
                Else
                    SommQ = cM & cOp & "0" & cP & vSSNm & cD & vSDv & cFp
                End If
            Else
                If vBSInt = vBSNm Then
                    If vBSInt = True Then
                        SommQ = vSSInt & cP & vSSNm & cD & vSDv
                    Else
                        SommQ = cM & cOp & vSSInt & cP & vSSNm & cD & vSDv & cFp
                    End If
                Else
                    vSSInt = DiffN(vSSInt, "1")
                    vSSNm = DiffN(vSDv, vSSNm)
                    If vBSInt = True Then
                        SommQ = vSSInt & cP & vSSNm & cD & vSDv
                    Else
                        SommQ = cM & cOp & vSSInt & cP & vSSNm & cD & vSDv & cFp
                    End If
                End If
            End If
        End If
    End Function
     
    Function SousQ(x As String, y As String) As String
    'fonction Soustraction de Q vers Q
    Dim vSNmx As String
    Dim vSNmy As String
    Dim vSDv As String
    Dim vSSNm As String
    Dim vBSNm As Boolean
    Dim vSSInt As String
    Dim vBSInt As Boolean
    Dim z1 As String
    Dim z2 As String
    Dim v1 As Boolean
    Dim v2 As Boolean
    Dim v3 As String
    Dim v4 As String
    Dim v5 As String
    Dim v6 As String
    Dim v7 As String
    Dim v8 As String
        v5 = IdenQ(x, 2)   '6
        v6 = IdenQ(y, 2)   '3
        v7 = IdenQ(x, 3)   '8
        v8 = IdenQ(y, 3)   '7
        'Partie numérateur de x pour le multiplicateur commun de x,y
        vSNmx = ProdN(v5, v8)
        'Partie numérateur de y pour le multiplicateur commun de x,y
        vSNmy = ProdN(v7, v6)
        'Multiplicateur commun de x,y
        vSDv = ProdN(v7, v8)
        v1 = SignQ(x)
        v2 = SignQ(y)
        v3 = IdenQ(x, 1)
        v4 = IdenQ(y, 1)
        'opérations intermédiaires
        If v1 <> v2 Then
            vSSNm = SommN(vSNmx, vSNmy)
            vBSNm = v1
            vSSInt = SommN(v3, v4)
            vBSInt = v1
            If XseYN(vSSNm, vSDv) = True Then
                vSSNm = DiffN(vSSNm, vSDv)
                vSSInt = SommN(vSSInt, "1")
            End If
        Else
            vSSNm = DiffN(vSNmx, vSNmy)
            If XseYN(vSNmx, vSNmy) = True Then
                vBSNm = v1
            Else
                vBSNm = Not (v1)
            End If
            vSSInt = DiffN(v3, v4)
            If XseYN(v3, v4) = True Then
                vBSInt = v1
            Else
                vBSInt = Not (v1)
            End If
        End If
        'Résultat
        If vSSNm = "0" Then
            If vBSInt = True Then
                SousQ = vSSInt
            Else
                If vSSInt = 0 Then
                    SousQ = "0"
                Else
                    SousQ = cM & vSSInt
                End If
            End If
        Else
            z1 = vSSNm
            z2 = vSDv
            vSSNm = SimpN(z1, z2, 1)
            vSDv = SimpN(z1, z2, 2)
            If vSSInt = "0" Then
                If vBSNm = True Then
                    SousQ = "0" & cP & vSSNm & cD & vSDv
                Else
                    SousQ = cM & cOp & "0" & cP & vSSNm & cD & vSDv & cFp
                End If
            Else
                If vBSInt = vBSNm Then
                    If vBSInt = True Then
                        SousQ = vSSInt & cP & vSSNm & cD & vSDv
                    Else
                        SousQ = cM & cOp & vSSInt & cP & vSSNm & cD & vSDv & cFp
                    End If
                Else
                    vSSInt = DiffN(vSSInt, "1")   '8
                    vSSNm = DiffN(vSDv, vSSNm)    '19
                    If vBSInt = True Then
                        SousQ = vSSInt & cP & vSSNm & cD & vSDv
                    Else
                        SousQ = cM & cOp & vSSInt & cP & vSSNm & cD & vSDv & cFp
                    End If
                End If
            End If
        End If
    End Function
     
    Function ProdQ(x As String, y As String) As String
    'fonction multiplication de Q vers Q
    Dim vBSS As Boolean
    Dim vSDv As String
    Dim vSNm1 As String
    Dim vSNm2 As String
    Dim vSNm3 As String
    Dim vSNm4 As String
    Dim vSNmF As String
    Dim vSInt As String
    Dim z1 As String
    Dim z2 As String
    Dim v1 As String
    Dim v2 As String
    Dim v3 As String
    Dim v4 As String
    Dim v5 As String
    Dim v6 As String
        vBSS = SignQ(x) Eqv SignQ(y)
        v1 = IdenQ(x, 1)
        v2 = IdenQ(y, 1)
        v3 = IdenQ(x, 2)
        v4 = IdenQ(y, 2)
        v5 = IdenQ(x, 3)
        v6 = IdenQ(y, 3)
        'opérations intermédiaires
        vSDv = ProdN(v5, v6)
        vSNm1 = ProdN(v1, v2)
        vSNm1 = ProdN(vSNm1, vSDv)
        vSNm2 = ProdN(v1, v4)
        vSNm2 = ProdN(vSNm2, v5)
        vSNm3 = ProdN(v2, v3)
        vSNm3 = ProdN(vSNm3, v6)
        vSNm4 = ProdN(v3, v4)
        vSNmF = SommN(vSNm1, vSNm2)
        vSNmF = SommN(vSNmF, vSNm3)
        vSNmF = SommN(vSNmF, vSNm4)
        vSInt = DiviN(vSNmF, vSDv, 1)
        vSNmF = DiviN(vSNmF, vSDv, 2)
        If XseYN(vSNmF, vSDv) = True Then
            vSInt = SommN(vSInt, "1")
            vSNmF = DiffN(vSNmF, vSDv)
        End If
        'résultat
        If vBSS = True Then
            If vSNmF = "0" Then
                ProdQ = vSInt
            Else
                z1 = vSNmF
                z2 = vSDv
                vSNmF = SimpN(z1, z2, 1)
                vSDv = SimpN(z1, z2, 2)
                ProdQ = vSInt & cP & vSNmF & cD & vSDv
            End If
        Else
            If vSNmF = "0" Then
                If vSInt <> "0" Then
                    ProdQ = cM & vSInt
                Else
                    ProdQ = vSInt
                End If
            Else
                z1 = vSNmF
                z2 = vSDv
                vSNmF = SimpN(z1, z2, 1)
                vSDv = SimpN(z1, z2, 2)
                ProdQ = cM & cOp & vSInt & cP & vSNmF & cD & vSDv & cFp
            End If
        End If
    End Function
     
    Function DiviQ(x As String, y As String) As String
    'fonction division de Q vers Q
    Dim vBSS As Boolean
    Dim v1 As String
    Dim v2 As String
    Dim v3 As String
    Dim v4 As String
    Dim v5 As String
    Dim v6 As String
    Dim vSNum As String
    Dim vSDen As String
    Dim vSInt As String
    Dim z1 As String
    Dim z2 As String
        vBSS = SignQ(x) Eqv SignQ(y)
        v1 = IdenQ(x, 1)
        v2 = IdenQ(y, 1)
        v3 = IdenQ(x, 2)
        v4 = IdenQ(y, 2)
        v5 = IdenQ(x, 3)
        v6 = IdenQ(y, 3)
        If v2 = "0" Then
            If v4 = "0" Then
                DiviQ = ceD0
                Exit Function
            End If
        End If
        vSNum = ProdN(v1, v5)
        vSNum = SommN(vSNum, v3)
        vSNum = ProdN(vSNum, v6)
        vSDen = ProdN(v2, v6)
        vSDen = SommN(vSDen, v4)
        vSDen = ProdN(vSDen, v5)
        vSInt = DiviN(vSNum, vSDen, 1)
        vSNum = DiviN(vSNum, vSDen, 2)
        'résultat
        If vBSS = True Then
            If vSNum = "0" Then
                DiviQ = vSInt
            Else
                z1 = vSNum
                z2 = vSDen
                vSNum = SimpN(z1, z2, 1)
                vSDen = SimpN(z1, z2, 2)
                DiviQ = vSInt & cP & vSNum & cD & vSDen
            End If
        Else
            If vSNum = "0" Then
                If vSInt <> "0" Then
                    DiviQ = cM & vSInt
                Else
                    DiviQ = vSInt
                End If
            Else
                z1 = vSNum
                z2 = vSDen
                vSNum = SimpN(z1, z2, 1)
                vSDen = SimpN(z1, z2, 2)
                DiviQ = vSInt & cP & vSNum & cD & vSDen
                DiviQ = cM & cOp & vSInt & cP & vSNum & cD & vSDen & cFp
            End If
        End If
    End Function
    Les autres fonctions nécessaires :
    Bien que n'étant pas directement destinées à l'utilisateur mais aux autres fonctions je ne les ai pas déclarées privées car il m'arrive de les utiliser directement, notamment pour les calculs dans N ou elles sont plus rapides. Toutefois, dans ce cas, il faut se rappeler que les entrées doivent être correctement formatées. Par exemple 02344445456555566666 pourra provoquer un résultat erroné selon la fonction employée à cause du 0 à gauche. Voir le code pour une description de chaque fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    Function IdenQ(x As String, Arg As Byte) As String
    'renvoie la partie entiere (1), le numérateur (2) ou le diviseur (3) d'une chaine Q correcte
    Dim vIcDP As Long       'position du symbole de division
    Dim vIcPP As Long       'position du symbole d'addition
    Dim vBFc As Boolean     'indicateur partie fractionnaire pour x
        'Partie fractionnaire?
        vIcDP = InStr(1, x, cD)
        vIcPP = InStr(1, x, cP)
        If vIcDP > 0 Then
            vBFc = True
        Else
            vBFc = False
        End If
        'Attribution des variables entier, numérateur, dénominateur pour x
        If SignQ(x) = True Then
            If vBFc = True Then
                Select Case Arg
                    Case 1
                        IdenQ = Left(x, vIcPP - 1)
                    Case 2
                        IdenQ = Right(Left(x, vIcDP - 1), vIcDP - 1 - vIcPP)
                    Case 3
                        IdenQ = Right(x, Len(x) - vIcDP)
                End Select
            Else
                Select Case Arg
                    Case 1
                        IdenQ = x
                    Case 2
                        IdenQ = "0"
                    Case 3
                        IdenQ = "1"
                End Select
            End If
        Else
            If vBFc = True Then
                Select Case Arg
                    Case 1
                        IdenQ = Right(Left(x, vIcPP - 1), vIcPP - 3)
                    Case 2
                        IdenQ = Right(Left(x, vIcDP - 1), vIcDP - 1 - vIcPP)
                    Case 3
                        IdenQ = Left(Right(x, Len(x) - vIcDP), Len(x) - vIcDP - 1)
                End Select
            Else 'Z
                Select Case Arg
                    Case 1
                        IdenQ = Right(x, Len(x) - 1)
                    Case 2
                        IdenQ = "0"
                    Case 3
                        IdenQ = "1"
                End Select
            End If
        End If
        IdenQ = Sp0GN(IdenQ)
    End Function
    Function ProdN(x As String, y As String) As String
    'N->x*y, suppose Sup0 fait
    Dim vILnx As Integer    'Len(x)
    Dim vILny As Integer    'Len(y)
    Dim vSRs As String      'Chaine résultat
    Dim vIMxL As Integer    'Max(vILnx, vILny)
    Dim vIMnL As Integer    'Min(vILnx, vILny)
    Dim vSPArg As String    'Min(x,y)
    Dim vSGArg As String    'Max(x,y)
    Dim vbRt As Byte        'Retenue
    Dim vbCx As Byte        'Caractères successifs de x
    Dim vbCy As Byte        'Caractères successifs de y
    Dim vbSC As Byte        'vbCx-vbCy
    Dim vSRsI1 As String    'chaine résultat intermédiaire 1
    Dim vSRsI2 As String    'chaine résultat intermédiaire 2
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer
        vILnx = Len(x)
        vILny = Len(y)
        vSRs = "0"
        If XseYN(x, y) = True Then
            vIMxL = vILnx
            vIMnL = vILny
            vSPArg = y
            vSGArg = x
        Else
            vIMxL = vILny
            vIMnL = vILnx
            vSPArg = x
            vSGArg = y
        End If
        For i = 1 To vIMnL
            vSRsI1 = ""
            vbRt = 0
            vbCx = Left(Right(vSPArg, i), 1)
            For j = 1 To vIMxL
                vbCy = Left(Right(vSGArg, j), 1)
                vbSC = (vbCx * vbCy) + vbRt
                vbRt = Int(vbSC / 10)
                vbSC = vbSC - 10 * vbRt
                vSRsI1 = vbSC & vSRsI1
            Next j
            If vbRt > 0 Then
                vSRsI2 = vbRt & vSRsI1
            Else
                vSRsI2 = vSRsI1
            End If
            If i = 1 Then
                vSRs = vSRsI2
            Else
                For k = 2 To i
                    vSRsI2 = vSRsI2 & "0"
                Next k
                vSRs = SommN(vSRsI2, vSRs)
            End If
        Next i
        ProdN = Sp0GN(vSRs)
    End Function
    Function SignQ(x As String) As Boolean
    'renvoie le signe (+ true, - false) d'une chaine Q
        If Left(x, 1) = cM Then
            SignQ = False
        Else
            SignQ = True
        End If
    End Function
    Function SommN(x As String, y As String) As String
    'N->x+y, suppose Sup0 fait
    Dim vILnx As Integer    'Len(x)
    Dim vILny As Integer    'Len(y)
    Dim vSRs As String      'Chaine résultat
    Dim vbRt As Byte        'Retenue
    Dim vIMxL As Integer    'Max(vILnx, vILny)
    Dim vbCx As Byte        'Caractères successifs de x
    Dim vbCy As Byte        'Caractères successifs de y
    Dim vbSC As Byte        'vbCx+vbCy
    Dim i As Integer
        vILnx = Len(x)
        vILny = Len(y)
        vSRs = ""
        vbRt = 0
        If XseYN(x, y) = True Then
            vIMxL = vILnx
        Else
            vIMxL = vILny
        End If
        For i = 1 To vIMxL
            vbCx = Left(Right(x, i), 1)
            If i > vILnx Then vbCx = 0
            vbCy = Left(Right(y, i), 1)
            If i > vILny Then vbCy = 0
            vbSC = vbCx + vbCy + vbRt
            If vbSC < 10 Then
                vbRt = 0
            Else
                vbSC = vbSC - 10
                vbRt = 1
            End If
            vSRs = vbSC & vSRs
        Next i
        If vbRt = 1 Then
            SommN = "1" & vSRs
        Else
            SommN = vSRs
        End If
    End Function
    Function XseYN(x As String, y As String) As Boolean
    'N->détermine si x>=y, suppose Sup0 fait
    Dim vILnx As Integer    'Len(x)
    Dim vILny As Integer    'Len(y)
    Dim vbCx As Byte        'Caractères successifs de x
    Dim vbCy As Byte        'Caractères successifs de y
    Dim i As Integer
        vILnx = Len(x)
        vILny = Len(y)
        If vILnx > vILny Then
            XseYN = True
            Exit Function
        End If
        If vILnx < vILny Then
            XseYN = False
            Exit Function
        End If
        For i = 1 To vILnx
                vbCx = Right(Left(x, i), 1)
                vbCy = Right(Left(y, i), 1)
                If vbCx > vbCy Then
                    XseYN = True
                    Exit Function
                End If
                If vbCy > vbCx Then
                    XseYN = False
                    Exit Function
                End If
        Next i
        XseYN = True
    End Function
    Function DiffN(x As String, y As String) As String
    'N->Abs(x-y), suppose Sup0 fait
    Dim vILnx As Integer    'Len(x)
    Dim vILny As Integer    'Len(y)
    Dim vSRs As String      'Chaine résultat
    Dim vbRt As Byte        'Retenue
    Dim vIMxL As Integer    'Max(vILnx, vILny)
    Dim xBis As String      'Max (x, y)
    Dim yBis As String      'Min(x, y)
    Dim vbCx As Byte        'Caractères successifs de x
    Dim vbCy As Byte        'Caractères successifs de y
    Dim vISC As Integer     'vbCx-vbCy
    Dim i As Integer
        vILnx = Len(x)
        vILny = Len(y)
        vSRs = ""
        vbRt = 0
        If XseYN(x, y) = True Then
            vIMxL = vILnx
            xBis = x
            yBis = y
        Else
            vIMxL = vILny
            xBis = y
            yBis = x
            vILnx = Len(y)
            vILny = Len(x)
        End If
        For i = 1 To vIMxL
            vbCx = Left(Right(xBis, i), 1)
            vbCy = Left(Right(yBis, i), 1)
            If i > vILny Then vbCy = 0
            vISC = CInt(vbCx) - CInt(vbCy) - CInt(vbRt)
            If vbCx < vbCy + vbRt Then
                vISC = vISC + 10
                vbRt = 1
            Else
                vbRt = 0
            End If
            vSRs = vISC & vSRs
        Next i
        DiffN = Sp0GN(vSRs)
    End Function
    Function SimpN(x As String, y As String, Arg As Byte) As String
    'N->renvoie de la fraction x/y (1) le numérateur, (2) le diviseur, après simplification, suppose Sup0 fait
    Dim vSCD As String      'diviseur commun
    Dim vSSVx As String     'Valeurs successives à tester issue de x
    Dim vSSVy As String     'Valeurs successives à tester issue de y
    Dim v1 As String
    Dim v2 As String
        If y = "0" Then
            SimpN = ceD0
            Exit Function
        End If
        vSSVx = x
        vSSVy = y
        vSCD = "1"
    Line1:
        'test fin
        If XseYN("1", vSSVx) = True Then GoTo Line2
        If XseYN("1", vSSVy) = True Then GoTo Line2
        v1 = NDivN(vSSVx, "1")
        v2 = NDivN(vSSVy, "1")
        If v1 = v2 Then
            'incrémente diviseur commun
            vSCD = ProdN(v1, vSCD)
            'Ajuste les valeurs à tester
            vSSVx = DiviN(vSSVx, v1, 1)
            vSSVy = DiviN(vSSVy, v1, 1)
        Else
            If XseYN(v1, v2) = True Then
                'Ajuste la valeur à tester issue de y
                vSSVy = DiviN(vSSVy, v2, 1)
            Else
                'Ajuste la valeur à tester issue de x
                vSSVx = DiviN(vSSVx, v1, 1)   '3 1
            End If
        End If
        GoTo Line1
    Line2:
        Select Case Arg
            Case 1
                SimpN = DiviN(x, vSCD, 1)
            Case 2
                SimpN = DiviN(y, vSCD, 1)
        End Select
    End Function
    Function Sp0GN(x As String) As String
    'supprime les 0 à gauche
    Dim i As Integer
    Dim vSSV As String
        vSSV = x
        For i = 1 To Len(vSSV) - 1
            If Left(vSSV, 1) = 0 Then
                vSSV = Right(vSSV, Len(vSSV) - 1)
            Else
                Sp0GN = vSSV
                Exit Function
            End If
        Next i
        Sp0GN = vSSV
    End Function
    Function NDivN(x As String, Arg As String) As String
    'N->renvoie le Argème diviseur de x dans N, suppose Sup0 fait
    'Si x = 0 donne 0
    'Si x = 1 donne 1
    'Si Arg dépasse le nombre de diviseur donne 1
    'Si limite diviseur testé dépassée donne x/produits des arguments précédents
    'dans tous les cas x=Produit des nièmes diviseurs de 1 à n si n suffisement grand
    Dim vSCpt As String     'compteur
    Dim vSTD As String      'diviseur testé
    Dim vSSVx As String     'valeurs successives de x
    Dim vLRw As Long        'Ligne du diviseur à tester
    Dim oWs As Worksheet
    Dim vLMx As Long
        Set oWs = Worksheets(cSN1)
        vLMx = oWs.Cells(Rows.Count, cCol).End(xlUp).Row
        If x = "0" Then
            NDivN = "0"
            GoTo Line99
        End If
        If x = "1" Then
            NDivN = "1"
            GoTo Line99
        End If
        vSCpt = "0"
        vSTD = "1"
        vSSVx = x
        vLRw = 1
    Line1:
        vLRw = vLRw + 1
        If vLRw > vLMx Then
            vSSVx = x
    Line3:
            Select Case Arg
                Case "1"
                    NDivN = vSSVx
                Case Else
                    vSSVx = DiviN(vSSVx, NDivN(vSSVx, DiffN(Arg, "1")), 1)
                    Arg = DiffN(Arg, "1")
                    GoTo Line3
            End Select
            GoTo Line99
        End If
    Line2:
        If DiviN(vSSVx, oWs.Cells(vLRw, cCol), 2) = "0" Then
            vSCpt = SommN(vSCpt, "1")
            vSSVx = DiviN(vSSVx, oWs.Cells(vLRw, cCol), 1)
            If vSCpt = Arg Then
                NDivN = oWs.Cells(vLRw, cCol)
                GoTo Line99
            Else
                If vSSVx = "1" Then
                    NDivN = "1"
                Else
                    GoTo Line2
                End If
            End If
        Else
            If XseYN(DiviN(vSSVx, oWs.Cells(vLRw, cCol), 1), oWs.Cells(vLRw, cCol)) = False Then
                vSCpt = SommN(vSCpt, "1")
                If vSCpt = Arg Then
                    NDivN = vSSVx
                Else
                    NDivN = "1"
                End If
                GoTo Line99
            End If
            GoTo Line1
        End If
    Line99:
        Set oWs = Nothing
    End Function
    Function DiviN(x As String, y As String, Arg As Byte) As String
    'N->x/y renvoie (1) Int(x/y) (2) Mod(x/y), suppose Sup0 fait
    Dim vILnx As Integer    'Len(x)
    Dim vILny As Integer    'Len(y)
    Dim vSRsE As String     'Chaine résultat entiere
    Dim vSRsR As String     'Chaine résultat reste
    Dim vSCx As String      'Caractères successifs de x
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer
    Dim vj As String
    Dim v1 As String
    Dim v2 As String
    Dim v3 As String
        If XseYN(x, y) = False Then
            Select Case Arg
                Case 1
                    DiviN = "0"
                Case 2
                    DiviN = x
            End Select
            Exit Function
        End If
        vILnx = Len(x)
        vILny = Len(y)
        vSRsE = ""
        vSRsR = ""
        vSCx = Left(x, vILny) '2
        For i = vILny To vILnx
            For j = 0 To 9
                k = j + 1   '1
                vj = k      '1
                If XseYN(vSCx, ProdN(vj, y)) = False Then
                    vSRsE = vSRsE & j
                    vj = j
                    v1 = vSCx
                    v2 = ProdN(vj, y)
                    v3 = DiffN(v1, v2)
                    If i < vILnx Then
                        vSCx = Sp0GN(v3 & Right(Left(x, i + 1), 1))
                    End If
                    GoTo Line1
                End If
            Next j
    Line1:
        Next i
        vSRsE = Sp0GN(vSRsE)
        If vSRsE = "" Then
            DiviN = ceD0
            Exit Function
        End If
        Select Case Arg
            Case 1
                DiviN = vSRsE
            Case 2
                DiviN = v3
        End Select
    Line2:
    End Function
    Tous commentaires, proposition d'optimisation bienvenus. Prochaine amélioration prévue : ne pas charger le csv des premiers mais y faire des requêtes.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 84
    Points
    84
    Par défaut Fonction complémentaire
    Nombre rationnel aléatoire.
    Cette fonction a servi à générer les colonnes A et B du tableau posté dans le post précédent avec les entrées VRAI,10,100 (inclure nombres négatifs,partie entière maximum,dénominateur partie fractionnaire maximum)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    Function AleaQ(vBNeg As Boolean, vLIntM As Long, vLDenM As Long) As String
    'Génération de nombres Q aléatoires
    'entrées nombres négatifs et positif (true) ou seulement positif (false)
    'Partie entière max, dénominateur max
    Dim vLInt As Long
    Dim vLNum As Long
    Dim vLDen As Long
    Dim vStr As String
    Dim vbNP As Byte
    Dim z1 As String
    Dim z2 As String
        vLInt = Application.WorksheetFunction.RandBetween(0, vLIntM)
        vLDen = Application.WorksheetFunction.RandBetween(1, vLDenM)
        vLNum = Application.WorksheetFunction.RandBetween(0, vLDen - 1)
        z1 = vLNum
        z2 = vLDen
        vLNum = SimpN(z1, z2, 1)
        vLDen = SimpN(z1, z2, 2)
        If vLNum = 0 Then
            vStr = vLInt
        Else
            vStr = vLInt & cP & vLNum & cD & vLDen
        End If
        If vBNeg = False Then
            AleaQ = vStr
            Exit Function
        Else
            vbNP = Application.WorksheetFunction.RandBetween(0, 1)
            If vbNP = 1 Then
                AleaQ = vStr
                Exit Function
            Else
                If vLNum = 0 Then
                    If vLInt = 0 Then
                        AleaQ = vStr
                        Exit Function
                    Else
                        AleaQ = cM & vStr
                        Exit Function
                    End If
                Else
                    AleaQ = cM & cOp & vStr & cFp
                    Exit Function
                End If
            End If
        End If
    End Function

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 84
    Points
    84
    Par défaut
    Bonjour,

    Annule et remplace le post précédent.

    Ecrit avec Excel 2007 mais probablement compatible avec les versions précédentes.

    Deux copies d'écran pour avoir une bonne idée des fonctions :






    Les fonctions pour l'utilisateur :
    SmQ : somme des deux entrées
    SsQ : 2ème entrée ôtée de la 1ère entrée
    PrQ : produit des deux entrées
    DvQ : 1ère entrée divisée par la seconde

    Ces fonctions imbricables sont à utiliser avec parcimonie, je conseille procéder par tests de difficultés croissants, de sauvegarder souvent son travail, il est très facile de lancer Excel dans des calculs considérables.
    A titre d'exemple le 1er tableau en copie d'écran a été généré en 3 secondes, le second en 20 secondes.

    Présentation des résultats :
    La partie fractionnaire est toujours positive et < 1. Voir le post précédent pour une définition plus rigoureuse.
    Les symboles utilisés (_,+,/,(,)) sont des constantes. Je déconseille l'utilisation du - comme symbole négatif. La seule contrainte est de n'utiliser qu'un seul caractère.

    L'utilisation d'une table des nombres premiers a été abandonnée pour la simplification des fractions. Il s'avère qu'un simple algorithme est bien plus rapide et permet d'avoir un classeur à vide d'un poids négligeable.

    Toutes les fonctions ont été 'nettoyées' voire optimisées. Le tout est à coller dans un module standard.

    Tous commentaires, proposition d'optimisation bienvenus. Prochaine amélioration prévue : passer de Q à "Q + racines".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    Option Explicit
     
    Public Const cP$ = "+":  Public Const cD$ = "/": Public Const cM$ = "_": Public Const cO$ = "(":  Public Const cF$ = ")"
    Public Const cD0$ = "Bad Entry"
     
    Public Const cR$ = "?"
     
    Function SmQ$(x$, y$)
    'addition Q->Q
    Dim p$(1 To 2, 1 To 3), b%(1 To 2, 1 To 2), c$(1 To 5), i%
    For i = 1 To 3
        p(1, i) = IdnQ(x, i): p(2, i) = IdnQ(y, i)
    Next i
    b(1, 1) = SgnQ(x): b(2, 1) = SgnQ(y)
    c(1) = PrdN(p(1, 2), p(2, 3)): c(2) = PrdN(p(1, 3), p(2, 2)): c(3) = PrdN(p(1, 3), p(2, 3))
    If b(1, 1) = b(2, 1) Then
        c(4) = SmmN(c(1), c(2)): b(1, 2) = b(1, 1): c(5) = SmmN(p(1, 1), p(2, 1)): b(2, 2) = b(1, 1)
        If XsYn(c(4), c(3)) Then
            c(4) = DffN(c(4), c(3)): c(5) = SmmN(c(5), 1)
        End If
    Else
        c(4) = DffN(c(1), c(2)): b(1, 2) = IIf(XsYn(c(1), c(2)), b(1, 1), b(2, 1))
        c(5) = DffN(p(1, 1), p(2, 1)): b(2, 2) = IIf(XsYn(p(1, 1), p(2, 1)), b(1, 1), b(2, 1))
    End If
    If Not CBool(c(4)) Then
        SmQ = IIf(b(2, 2), c(5), IIf(Not CBool(c(5)), 0, cM & c(5)))
    Else
        c(1) = c(3): c(3) = SmpN(c(4), c(3), 2): c(4) = SmpN(c(4), c(1), 1)
        If Not CBool(c(5)) Then
            SmQ = IIf(b(1, 2), 0 & cP & c(4) & cD & c(3), cM & cO & 0 & cP & c(4) & cD & c(3) & cF)
        Else
            If b(2, 2) = b(1, 2) Then
                SmQ = IIf(b(2, 2), c(5) & cP & c(4) & cD & c(3), cM & cO & c(5) & cP & c(4) & cD & c(3) & cF)
            Else
                If b(2, 2) Then
                    SmQ = DffN(c(5), 1) & cP & DffN(c(3), c(4)) & cD & c(3)
                Else
                    SmQ = cM & cO & DffN(c(5), 1) & cP & DffN(c(3), c(4)) & cD & c(3) & cF
                End If
            End If
        End If
    End If
    End Function
     
    Function PrQ$(x$, y$)
    'multiplication Q->Q
    Dim p$(1 To 2, 1 To 3), b%, c$(1 To 4), i%
    For i = 1 To 3
        p(1, i) = IdnQ(x, i): p(2, i) = IdnQ(y, i)
    Next i
    b = SgnQ(x) Eqv SgnQ(y)
    c(1) = PrdN(p(1, 3), p(2, 3))
    c(2) = SmmN(SmmN(SmmN(PrdN(PrdN(p(1, 1), p(2, 1)), c(1)), PrdN(PrdN(p(1, 1), p(2, 2)), p(1, 3))), _
        PrdN(PrdN(p(2, 1), p(1, 2)), p(2, 3))), PrdN(p(1, 2), p(2, 2)))
    c(3) = DvnN(c(2), c(1), 1): c(2) = DvnN(c(2), c(1), 2)
    If XsYn(c(2), c(1)) Then
        c(3) = SmmN(c(3), 1): c(2) = DffN(c(2), c(1))
    End If
        If b Then
            If Not CBool(c(2)) Then
                PrQ = c(3)
            Else
                c(4) = c(1): c(1) = SmpN(c(2), c(1), 2): c(2) = SmpN(c(2), c(4), 1)
                PrQ = c(3) & cP & c(2) & cD & c(1)
            End If
        Else
            If Not CBool(c(2)) Then
                PrQ = IIf(c(3) <> 0, cM & c(3), c(3))
            Else
                c(4) = c(1): c(1) = SmpN(c(2), c(1), 2): c(2) = SmpN(c(2), c(4), 1)
                PrQ = cM & cO & c(3) & cP & c(2) & cD & c(1) & cF
            End If
        End If
    End Function
     
    Function SsQ$(x$, y$)
    'soustraction Q->Q
    SsQ = SmQ(x, PrQ(y, "_1"))
    End Function
     
    Function DvQ$(x$, y$)
    'division Q->Q
    Dim p$(1 To 3), b%, i%
    If y = "0" Then
        DvQ = cD0
    Else
        For i = 1 To 3
            p(i) = IdnQ(y, i)
        Next i
        b = SgnQ(y): p(1) = SmmN(PrdN(p(1), p(3)), p(2)): p(2) = p(3)
        If b Then
            DvQ = PrQ(x, 0 & cP & p(2) & cD & p(1))
        Else
            DvQ = PrQ(x, cM & cO & 0 & cP & p(2) & cD & p(1) & cF)
        End If
    End If
    End Function
     
    Private Function SgnQ%(x$)
    'signe (true=0,+,false=-) Q
    If Left(x, 1) <> cM Then SgnQ = True
    End Function
     
    Private Function Sp0n$(x$)
    'supprime les 0 à gauche N
    Dim i%
    i = 1
    Do Until x = "" Or Left(x, 1) <> 0
        x = Right(x, Len(x) - 1): i = i + 1
    Loop
    Sp0n = IIf(x <> "", x, 0)
    End Function
     
    Private Function IdnQ$(x$, Arg%)
    'partie entiere (1), numérateur (2) diviseur (3) Q
    Dim pD&, pA&
    pD = InStr(1, x, cD): pA = InStr(1, x, cP)
    Select Case Arg
        Case 1
            If SgnQ(x) Then
                If pD > 0 Then
                    IdnQ = Left(x, pA - 1)
                Else
                    IdnQ = x
                End If
            Else
                If pD > 0 Then
                    IdnQ = Right(Left(x, pA - 1), pA - 3)
                Else
                    IdnQ = Right(x, Len(x) - 1)
                End If
            End If
        Case 2
            If pD = 0 Then
                IdnQ = 0
            Else
                IdnQ = Right(Left(x, pD - 1), pD - 1 - pA)
            End If
        Case 3
            If pD = 0 Then
                IdnQ = 1
            Else
                If SgnQ(x) Then
                    IdnQ = Right(x, Len(x) - pD)
                Else
                    IdnQ = Left(Right(x, Len(x) - pD), Len(x) - pD - 1)
                End If
            End If
    End Select
    IdnQ = Sp0n(IdnQ)
    End Function
     
    Private Function XsYn%(x$, y$)
    'N->x>=y?, suppose Sp0n fait
    Dim Cx%, Cy%, i%
    Select Case Len(x)
        Case Is > Len(y)
            XsYn = True
        Case Len(y)
            For i = 1 To Len(x)
                Cx = Right(Left(x, i), 1): Cy = Right(Left(y, i), 1)
                If Cx > Cy Then
                    XsYn = True: Exit Function
                End If
                If Cy > Cx Then Exit Function
            Next i
            XsYn = True
    End Select
    End Function
     
    Private Function SmmN$(x$, y$)
    'N->x+y, suppose Sup0 fait
    Dim r%, i%, Cx%, Cy%, Cz%
    For i = 1 To WorksheetFunction.Max(Len(x), Len(y))
        Cx = Left(Right(x, i), 1): If i > Len(x) Then Cx = 0
        Cy = Left(Right(y, i), 1): If i > Len(y) Then Cy = 0
        Cz = Cx + Cy + r
        If Cz < 10 Then
            r = 0
        Else
            Cz = Cz - 10: r = 1
        End If
        SmmN = Cz & SmmN
    Next i
    SmmN = Sp0n(r & SmmN)
    End Function
     
    Private Function DffN$(ByVal x$, ByVal y$)
    'N->Abs(x-y), suppose Sup0 fait
    Dim z$, Cx%, Cy%, r%, i%, Cz%
    If Not XsYn(x, y) Then
        z = x: x = y: y = z
    End If
    For i = 1 To WorksheetFunction.Max(Len(x), Len(y))
        Cx = Left(Right(x, i), 1): Cy = Left(Right(y, i), 1)
        If i > WorksheetFunction.Min(Len(x), Len(y)) Then Cy = 0
        Cz = Cx - Cy - r
        If Cx < Cy + r Then
            Cz = Cz + 10: r = 1
        Else
            r = 0
        End If
        DffN = Cz & DffN
    Next i
    DffN = Sp0n(DffN)
    End Function
     
    Private Function PrdN$(ByVal x$, ByVal y$)
    'N->x*y, suppose Sup0 fait
    Dim z$, r%, Cx%, Cy%, i%, j%, Cz%, k%, Rs1$, Rs2$
    PrdN = 0
    If Not XsYn(x, y) Then
        z = x: x = y: y = z
    End If
    For i = 1 To WorksheetFunction.Min(Len(x), Len(y))
        Rs1 = "": r = 0: Cx = Left(Right(y, i), 1)
        For j = 1 To WorksheetFunction.Max(Len(x), Len(y))
            Cy = Left(Right(x, j), 1): Cz = (Cx * Cy) + r: r = Int(Cz / 10): Cz = Cz - 10 * r: Rs1 = Cz & Rs1
        Next j
        Rs2 = IIf(r > 0, r & Rs1, Rs1)
        For k = 2 To i
            Rs2 = Rs2 & 0
        Next k
        PrdN = SmmN(Rs2, PrdN)
    Next i
    PrdN = Sp0n(PrdN)
    End Function
     
    Private Function DvnN$(x$, y$, Arg%)
    '(1) int(x/y), (2) x mod y, suppose Sup0 fait (N)
    Dim Cx$, i%, j%, v$, RsE$, RsR$
    If Not XsYn(x, y) Then
        DvnN = IIf(Arg = 1, 0, x): Exit Function
    End If
    Cx = Left(x, Len(y))
    For i = Len(y) To Len(x)
        For j = 0 To 9
            If Not XsYn(Cx, PrdN(j + 1, y)) Then
                RsE = RsE & j: v = DffN(Cx, PrdN(j, y))
                If i < Len(x) Then Cx = Sp0n(v & Right(Left(x, i + 1), 1))
                Exit For
            End If
        Next j
    Next i
    RsE = Sp0n(RsE)
    DvnN = Sp0n(IIf(Arg = 1, RsE, v))
    End Function
     
    Private Function SmpN$(x$, y$, Arg%)
    '(1) x/pgcd(x,y),(2) y/pgcd(x,y), suppose Sup0 fait (N)
    Dim a$, b$, c$
        a = x: b = y
        Do While DvnN(a, b, 2) <> 0
            c = a: a = b: b = DvnN(c, b, 2)
        Loop
        Select Case Arg
            Case 1
                SmpN = DvnN(x, b, 1)
            Case 2
                SmpN = DvnN(y, b, 1)
        End Select
    End Function

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 84
    Points
    84
    Par défaut
    Le post précédent est corrigé.

    En cas de nouvelle erreur repérée ou signalée ce post et le précédent seront actualisés.

    22/03/2011:
    Dans la fonction 'Sp0n$(x$)'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Do Until i = Len(x) Or Left(x, 1) <> 0
    à remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Do Until x = "" Or Left(x, 1) <> 0
    .

Discussions similaires

  1. Optimisation des opérations sur les grands nombres, algorithme de Knuth
    Par Jackyzgood dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 21/10/2010, 20h27
  2. Réponses: 14
    Dernier message: 05/10/2010, 15h26
  3. Opération sur des grands nombres
    Par Melem dans le forum Contribuez
    Réponses: 3
    Dernier message: 11/01/2008, 13h11
  4. Opérations sur les textures dans pixels shader
    Par ultimanu dans le forum DirectX
    Réponses: 10
    Dernier message: 27/04/2007, 09h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo