Gobillot
Messages postés
3140
Date d'inscription
vendredi 14 mai 2004
Statut
Membre
Dernière intervention
11 mars 2019
34
8 mars 2007 à 23:57
pas mal de modifications depuis:
j'ai maintenant 2 modules ( a et b)
le premier travaille en Long, le second en Double
bien que le Double est plus lent, je peux mettre plus de chiffres, 7 pour la multiplication au lieu de 4, et 14 pour les autres opérations au lieu de 9, donc le Double devient plus rapide.
la Fonction Arrondi permet de tronquer au nombre de chiffres significatifs (sauf si Tronq = False)
elle est utilisée par toutes les opérations sauf la division (qui elle calcule un chiffre en plus pour permettre l'arrondi)
ce qui permet d'avoir des résultats "exacts"
retrouver le dividende en multipliant par le quotient: (20 / 9) * 9 = 20
l'inverse de l'inverse doit donner le même nombre: (1 / (1 / 9) --> 9
la Division donne en prime le Modulo (en réel) et le Modulo donne en prime le quotient entier.
je donne tout le module b plus quelques publics du module a
j'espère avoir rien oublié
il y a encore pas mal de choses à revoir,
par exemple la division qui donne parfois beaucoup trop de zéro aprés la virgule
Option Explicit
Const chrz = "0"
Const sep = ","
Dim parm As Integer
Dim puis As Double
Dim frmt As String
Dim s1 As Byte
Dim s2 As Byte
Dim a1 As Integer
Dim a2 As Integer
Dim b1 As Integer
Dim b2 As Integer
Dim k As Integer
Public preci As Integer
Public pos As Integer
Public Modulo As String
Public Quotient As String
Public Tronq As Boolean
Public Function bAddition(n1 As String, n2 As String) As String
Dim a As String
Dim b As String
Dim i As Integer
Dim j As Integer
Dim x As Integer
parm = 14
puis = 10 ^ parm
frmt = String(parm, chrz)
i = InStr(n1, sep)
j = InStr(n2, sep) If i > 0 Then a1 i - 2: b1 Len(n1) - i Else a1 = Len(n1) - 1: b1 = 0 If j > 0 Then a2 j - 2: b2 Len(n2) - j Else a2 = Len(n2) - 1: b2 = 0 If b1 > b2 Then pos b1 Else pos b2
i = a1 + pos
j = a2 + pos If i > j Then k i Else k j
k = k + parm - (k Mod parm)
a = String$(k - i, chrz) & Mid$(n1, 2, a1) & Mid$(n1, a1 + 3, b1) & String$(pos - b1, chrz)
b = String$(k - j, chrz) & Mid$(n2, 2, a2) & Mid$(n2, a2 + 3, b2) & String$(pos - b2, chrz) s1 Asc(n1): s2 Asc(n2)
If s1 <> s2 Then
x = StrComp(a, b, vbBinaryCompare)
Select Case x
Case 1: bAddition = bSbb(a, b, s1)
Case 0: bAddition = "+0"
Case -1: bAddition = bSbb(b, a, s2)
End Select
Exit Function
End If
bAddition = bAdd(a, b, s1)
End Function
Public Function bSoustraction(n1 As String, n2 As String) As String
Dim a As String
Dim b As String
Dim i As Integer
Dim j As Integer
Dim x As Integer
parm = 14
puis = 10 ^ parm
frmt = String(parm, chrz)
i = InStr(n1, sep)
j = InStr(n2, sep) If i > 0 Then a1 i - 2: b1 Len(n1) - i Else a1 = Len(n1) - 1: b1 = 0 If j > 0 Then a2 j - 2: b2 Len(n2) - j Else a2 = Len(n2) - 1: b2 = 0 If b1 > b2 Then pos b1 Else pos b2
i = a1 + pos
j = a2 + pos If i > j Then k i Else k j
k = k + parm - (k Mod parm)
a = String$(k - i, chrz) & Mid$(n1, 2, a1) & Mid$(n1, a1 + 3, b1) & String$(pos - b1, chrz)
b = String$(k - j, chrz) & Mid$(n2, 2, a2) & Mid$(n2, a2 + 3, b2) & String$(pos - b2, chrz) s1 Asc(n1): s2 Asc(n2)
If s1 <> s2 Then
bSoustraction = bAdd(a, b, s1)
Exit Function
End If If s1 43 Then s2 45 Else s2 = 43
x = StrComp(a, b, vbBinaryCompare)
Select Case x
Case 1: bSoustraction = bSbb(a, b, s1)
Case 0: bSoustraction = "+0"
Case -1: bSoustraction = bSbb(b, a, s2)
End Select
End Function
Private Function bAdd(n1 As String, n2 As String, sg As Byte) As String
Dim c As String
Dim i As Integer
Dim j As Integer
Dim x As Integer
Dim r As Long
Dim t As Double
parm = 14
puis = 10 ^ parm
frmt = String(parm, chrz)
k = Len(n1)
c = String$(k, chrz)
For i = k + 1 - parm To 1 Step -parm
t = CDbl(Mid$(n1, i, parm)) + CDbl(Mid$(n2, i, parm)) + r
r = 0: If t >= puis Then r = 1: t = t - puis
Mid$(c, i, parm) = Format$(t, frmt)
Next
bAdd = Arrondi(c$, Chr$(sg))
End Function
Private Function bSbb(n1 As String, n2 As String, sg As Byte) As String
Dim c As String
Dim i As Integer
Dim j As Integer
Dim x As Integer
Dim r As Long
Dim t As Double
Dim v1 As Double
Dim v2 As Double
k = Len(n1)
c = String$(k, chrz)
For i = k + 1 - parm To 1 Step -parm
v1 = CDbl(Mid$(n1, i, parm)) v2 CDbl(Mid$(n2, i, parm)) + r: r 0 If v1 < v2 Then v1 v1 + puis: r 1
t = v1 - v2
Mid$(c, i, parm) = Format$(t, frmt)
Next
bSbb = Arrondi(c$, Chr$(sg))
End Function
Public Function bMultiplication(n1 As String, n2 As String) As String
Dim a As String
Dim b As String
Dim d As String
Dim sg As String
Dim i As Long
Dim j As Long
Dim ka As Integer
Dim kb As Integer
Dim x As Integer
Dim y As Integer
Dim z As Integer
Dim r As Long
Dim tt As Double
Dim v1 As Double
Dim v2 As Double
Dim W1() As Double
Dim W2() As Double
parm = 7
puis = 10 ^ parm
frmt = String(parm, chrz)
i = InStr(n1, sep)
j = InStr(n2, sep) If i > 0 Then a1 i - 2: b1 Len(n1) - i Else a1 = Len(n1) - 1: b1 = 0 If j > 0 Then a2 j - 2: b2 Len(n2) - j Else a2 = Len(n2) - 1: b2 = 0
pos = b1 + b2 If Asc(n1) Asc(n2) Then sg "+" Else sg = "-"
i a1 + b1: x parm - (i Mod parm): If x = parm Then x = 0 j a2 + b2: y parm - (j Mod parm): If y = parm Then y = 0
a = String$(y, chrz) & Mid$(n2, 2, a2) & Mid$(n2, a2 + 3, b2)
b = String$(x, chrz) & Mid$(n1, 2, a1) & Mid$(n1, a1 + 3, b1) ka y + j: kb x + i
x kb \ parm: k ka + kb: z = k \ parm
ReDim W1(x), W2(z)
i = 1
For j = kb + 1 - parm To 1 Step -parm W1(i) CDbl(Mid$(b, j, parm)): i i + 1
Next
y = 0
For i = ka + 1 - parm To 1 Step -parm
v1 = CDbl(Mid$(a, i, parm))
r = 0
For j = 1 To x
tt = W1(j) * v1 + W2(j + y) + r
r = Int(tt / puis)
W2(j + y) = tt - r * puis
Next
W2(j + y) = r
y = y + 1
Next
d$ = String(k, chrz)
j = 1
For i = z To 1 Step -1 Mid$(d$, j, parm) Format$(W2(i), frmt): j j + parm
Next
bMultiplication = Arrondi(d$, sg)
End Function
Public Function bDivision(n1 As String, n2 As String) As String
Dim a As String
Dim b As String
Dim c As String
Dim resu As String
Dim sg As String
Dim di As Integer
Dim dj As Integer
Dim i As Long
Dim j As Long
Dim r As Integer
Dim n As Integer
Dim p As Integer
Dim puis2 As Double
Dim q As Integer
Dim v1 As Double
Dim v2 As Double
Dim x As Integer
Dim z As Integer
Dim W1() As Double
Dim W2() As Double
If Mid$(n2, 2) = chrz Then Err.Raise 11
parm = 14
puis = 10 ^ parm
frmt = String(parm, chrz)
puis2 = puis / 10
i = InStr(n1, sep)
j = InStr(n2, sep) If i > 0 Then a1 i - 2: b1 Len(n1) - i Else a1 = Len(n1) - 1: b1 = 0 If j > 0 Then a2 j - 2: b2 Len(n2) - j Else a2 = Len(n2) - 1: b2 = 0 If b1 > b2 Then pos b1 Else pos b2
i = a1 + pos
j = a2 + pos If i > j Then k i Else k j di k - j: dj k - i
k = k + parm - (k Mod parm)
a = String$(k - i - dj, chrz) & Mid$(n1, 2, a1) & Mid$(n1, a1 + 3, b1) & String$(pos - b1 + dj, chrz)
b = String$(k - j - di, chrz) & Mid$(n2, 2, a2) & Mid$(n2, a2 + 3, b2) & String$(pos - b2 + di, chrz) If Asc(n1) Asc(n2) Then sg "+" Else sg = "-"
di = di + 1
pos = pos + dj
z = k \ parm
ReDim W1(z), W2(z) ' et W3(z)
i = 1
For j = k + 1 - parm To 1 Step -parm
W1(i) = CDbl(Mid$(a, j, parm)) W2(i) CDbl(Mid$(b, j, parm)): i i + 1
Next
' x = StrComp(a, b, vbBinaryCompare)
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
If dj > 0 Then
If x = -1 Then
dj = dj + 1
' a$ = Mid$(a$, 2) & "0"
r = 0
For j = 1 To z
v1 = W1(j)
v2 = Int(v1 / puis2)
W1(j) = (v1 - v2 * puis2) * 10 + r
r = v2
Next
End If
resu = "0," & String$(dj - 1, chrz)
p = 1: GoTo Boucle2
End If
If x = 0 Then
resu = "1" & String$(di - 1, chrz): GoTo Fin
End If
If x = -1 Then
If di > 1 Then
' b$ = "0" & Left$(b$, k - 1)
r = 0
For j = z To 1 Step -1
v1 = W2(j)
v2 = Int(v1 / 10)
W2(j) = v2 + r * puis2
r = v1 - v2 * 10
Next
di = di - 1
Else
' a$ = Mid$(a$, 2) & "0"
r = 0
For j = 1 To z
v1 = W1(j)
v2 = Int(v1 / puis2)
W1(j) = (v1 - v2 * puis2) * 10 + r
r = v2
Next
resu = resu & "0,"
p = 1: GoTo Boucle2
End If
End If
Boucle1:
For q = 1 To di
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
n = 0
While x <> -1
For i = 1 To z
v1 = W1(i) v2 W2(i) + r: r 0 If v1 < v2 Then v1 v1 + puis: r 1
W1(i) = v1 - v2
Next
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
n = n + 1
Wend
If q < di Then
' b$ = "0" & Left$(b$, k - 1)
r = 0
For j = z To 1 Step -1
v1 = W2(j)
v2 = Int(v1 / 10)
W2(j) = v2 + r * puis2
r = v1 - v2 * 10
Next
End If
resu = resu & n
Next
If preci + 1 > di Then resu = resu & sep
j = 1
For i = z To 1 Step -1 Mid$(a$, j, parm) Format$(W1(i), frmt): j j + parm
Next
' a$ = Mid$(a$, 2) & "0"
r = 0
For j = 1 To z
v1 = W1(j)
v2 = Int(v1 / puis2)
W1(j) = (v1 - v2 * puis2) * 10 + r
r = v2
Next
Boucle2:
If pos = 0 Then
Modulo = a$
Else
Modulo = Left$(a$, k - pos) & sep & Right$(a$, pos)
End If
dj = preci + 1 - di + p
For q = 1 To dj
' x = StrComp(a, b, vbBinaryCompare)
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
n = 0
While x <> -1
For i = 1 To z
v1 = W1(i) v2 W2(i) + r: r 0 If v1 < v2 Then v1 v1 + puis: r 1
W1(i) = v1 - v2
Next
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
n = n + 1
Wend
If q < dj Then
resu = resu & n
x = 0
For j = 1 To z
If W1(j) > 0 Then x = 1: Exit For
Next
If x = 0 Then
For i = Len(resu) To di + 2 Step -1
If Mid$(resu, i, 1) <> chrz Then Exit For
Next If i di + 1 Then i di
resu = Left$(resu, i)
GoTo Fin
End If
Else
If n > 0 Then resu = resu & n
GoTo Fin
End If
' a$ = Mid$(a$, 2) & "0"
r = 0
For j = 1 To z
v1 = W1(j)
v2 = Int(v1 / puis2)
W1(j) = (v1 - v2 * puis2) * 10 + r
r = v2
Next
Next
Fin:
bDivision = sg & resu
End Function
Public Function bModulo(n1 As String, n2 As String) As String
Dim a As String
Dim b As String
Dim c As String
Dim resu As String
Dim sg As String
Dim di As Integer
Dim dj As Integer
Dim i As Long
Dim j As Long
Dim r As Integer
Dim n As Integer
Dim p As Integer
Dim puis2 As Double
Dim q As Integer
Dim v1 As Double
Dim v2 As Double
Dim x As Integer
Dim z As Integer
Dim W1() As Double
Dim W2() As Double
If Mid$(n2, 2) = chrz Then Err.Raise 11
parm = 14
puis = 10 ^ parm
frmt = String(parm, chrz)
puis2 = puis / 10
i = InStr(n1, sep)
j = InStr(n2, sep) If i > 0 Then a1 i - 2: b1 Len(n1) - i Else a1 = Len(n1) - 1: b1 = 0 If j > 0 Then a2 j - 2: b2 Len(n2) - j Else a2 = Len(n2) - 1: b2 = 0 If b1 > b2 Then pos b1 Else pos b2
i = a1 + pos
j = a2 + pos If i > j Then k i Else k j di k - j: dj k - i
k = k + parm - (k Mod parm)
a = String$(k - i - dj, chrz) & Mid$(n1, 2, a1) & Mid$(n1, a1 + 3, b1) & String$(pos - b1 + dj, chrz)
b = String$(k - j - di, chrz) & Mid$(n2, 2, a2) & Mid$(n2, a2 + 3, b2) & String$(pos - b2 + di, chrz) If Asc(n1) Asc(n2) Then sg "+" Else sg = "-"
di = di + 1
pos = pos + dj
z = k \ parm
ReDim W1(z), W2(z) ' et W3(z)
i = 1
For j = k + 1 - parm To 1 Step -parm
W1(i) = CDbl(Mid$(a, j, parm)) W2(i) CDbl(Mid$(b, j, parm)): i i + 1
Next
' x = StrComp(a, b, vbBinaryCompare)
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
If dj > 0 Then
If x = -1 Then
dj = dj + 1
' a$ = Mid$(a$, 2) & "0"
r = 0
For j = 1 To z
v1 = W1(j)
v2 = Int(v1 / puis2)
W1(j) = (v1 - v2 * puis2) * 10 + r
r = v2
Next
End If
resu = "0": GoTo Fin
End If
If x = 0 Then
resu = "1" & String$(di - 1, chrz): GoTo Fin
End If
If x = -1 Then
If di > 1 Then
' b$ = "0" & Left$(b$, k - 1)
r = 0
For j = z To 1 Step -1
v1 = W2(j)
v2 = Int(v1 / 10)
W2(j) = v2 + r * puis2
r = v1 - v2 * 10
Next
di = di - 1
Else
' a$ = Mid$(a$, 2) & "0"
r = 0
For j = 1 To z
v1 = W1(j)
v2 = Int(v1 / puis2)
W1(j) = (v1 - v2 * puis2) * 10 + r
r = v2
Next
resu = resu & "0": GoTo Fin
End If
End If
Boucle1:
For q = 1 To di
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
n = 0
While x <> -1
For i = 1 To z
v1 = W1(i) v2 W2(i) + r: r 0 If v1 < v2 Then v1 v1 + puis: r 1
W1(i) = v1 - v2
Next
x = 0
For j = z To 1 Step -1
If W1(j) < W2(j) Then x = -1: Exit For
If W1(j) > W2(j) Then x = 1: Exit For
Next
n = n + 1
Wend
If q < di Then
' b$ = "0" & Left$(b$, k - 1)
r = 0
For j = z To 1 Step -1
v1 = W2(j)
v2 = Int(v1 / 10)
W2(j) = v2 + r * puis2
r = v1 - v2 * 10
Next
End If
resu = resu & n
Next
j = 1
For i = z To 1 Step -1 Mid$(a$, j, parm) Format$(W1(i), frmt): j j + parm
Next
Fin:
Quotient = sg & resu
sg = Left$(n1, 1)
bModulo = Arrondi(a$, sg)
End Function
Private Function Arrondi(a As String, sg As String) As String
Dim i As Integer
Dim j As Integer
Dim x As Integer
Dim r As Long
Dim t As Double
Dim z As Integer
x = k + 1 - pos
' suppression des zéros devant
For i = 1 To x - 2
If Mid$(a$, i, 1) <> chrz Then Exit For
Next
' suppression des zéros derrière
For j = k To x Step -1
If Mid$(a$, j, 1) <> chrz Then Exit For
Next
a1 = x - i
b1 = j + 1 - x
If Tronq Then b2 preci - a1: If b2 < 0 Then b2 0
If b2 < b1 Then
If Mid$(a$, x + b2, 1) > "4" Then
z% = x + b2 - 1 j z% Mod parm: If j 0 Then j = parm
j = z% - j + 1
r = 10 ^ ((k - z%) Mod parm)
While r > 0
t = CDbl(Mid$(a$, j, parm)) + r
r = 0 If t >puis Then r 1: t = t - puis
Mid$(a$, j, parm) = Format$(t, frmt)
j = j - parm
Wend
End If If Mid$(a$, i - 1, 1) <> chrz Then i i - 1: a1 a1 + 1
For j = x + b2 - 1 To x Step -1
If Mid$(a$, j, 1) <> chrz Then Exit For
Next
b1 = j + 1 - x
End If
End If
Arrondi = sg & Mid$(a$, i, a1)
If b1 > 0 Then Arrondi = Arrondi & sep & Mid$(a$, x, b1)
End Function
Daniel