FONCTION SWAP POUR NOMBRE ENTIER

cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 - 27 juin 2004 à 14:01
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 - 27 juin 2004 à 20:31
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/24064-fonction-swap-pour-nombre-entier

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
27 juin 2004 à 20:31
lol Renfield : C'est exactement ce qu'il y a dans la fonction publiée il y a quelques temps !
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
27 juin 2004 à 17:54
a supposer que la création d'un fonction juste pour ca soit justifiée...

on pourrait utiliser des Variant

private Sub Swap ( A as variant , b as variant )
Dim tmp as variant
tmp = a
a = b
b = tmp
end sub


au fait, LightAngel, plutot que de passer en parametre une chaine representant le type de variable, utilises Vartype ( N1 ) par exemple (ou TypeName :( )
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
27 juin 2004 à 17:33
Na na na na nè reuuu
C'est quand même la mienne la plus pratiqueuuuu !
lol
gandalfkhorne Messages postés 70 Date d'inscription dimanche 11 janvier 2004 Statut Membre Dernière intervention 1 octobre 2004
27 juin 2004 à 15:49
Bah merci, ca leve toujours certain doute, mais le but de cette source était de montré comment effectuer un swap sans utiliser de variable autre que celle que l'on a déjà, de plus si on fait d'une autre façon soit ou en soustrayant et en additionnant on risque de dépasser l'intervalle.
cs_Light Angel Messages postés 48 Date d'inscription dimanche 9 mai 2004 Statut Membre Dernière intervention 1 janvier 2005
27 juin 2004 à 15:03
Salut, je crois qu'il y a une autre manière plus simple pour faire un Swap en une fonction qui comprend tout les types :

Public Function Swap (N1 as Object, N2 as Object, Type as String)
Select Case Type
Case "int"
Dim Temp as Integer
Temp = CInt (N1)
N1 = CInt (N2)
N2 = CInt (Temp)
Case "dbl"
Dim Temp as Double
Temp = CDbl (N1)
N1 = CDbl (N2)
N2 = CDbl (Temp)
Case "sht"
Dim Temp as Short
Temp = CShort (N1)
N1 = CShort (N2)
N2 = CShort (Temp)
' Et on continue la fonction comme sa avec tous les type désiré
End Select
End Sub

Enfin, il y a quand même plus simple, mais avec VB .Net ou bien le C++ (La surcharge) ...

A+
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
27 juin 2004 à 14:45
NENNI, jamais 2 operandes memoire sur 1 instruction.
xor reg, mem
ou: xor mem, reg
cs_Zeroc00l Messages postés 367 Date d'inscription lundi 1 avril 2002 Statut Membre Dernière intervention 11 février 2010
27 juin 2004 à 14:39
Autrement dit la méthode "traditionnelle" qui consiste à créé une variable de "backup" est plus rapide ?

Hum ... à la manière du C++ et de sa syntaxe sympathique du style a += b ...

Pourrait-t-on faire en assembleur directement un swap comme ceci :

Nb1 xor= Nb2
Nb2 xor= Nb1
Nb1 xor= Nb2

??? Dans ce cas il n'y aurait plus création temporaire d'une variable utilisée à calculer les résultat pas à pas...

Je pense que pour cela quelques retouches en assembleur du code sont obligatoire..
Qu'en pensez vous ?
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
27 juin 2004 à 14:01
Oui la technique est sympathique mais le resultat l'est deja moins
au lieu de rentrer dans de l'on discour faispons un teste. imaginons
quand meme que l'on enleve au minimum la gestion d'erreur pour
alleger le tout voila le bench :

Voici les deux fonction comparé :

Sub SwapLng(ByRef Nb1 As Long, ByRef Nb2 As Long)
Nb1 = Nb1 Xor Nb2
Nb2 = Nb1 Xor Nb2
Nb1 = Nb1 Xor Nb2
End Sub

Sub Swap(ByRef v1 As Long, ByRef v2 As Long)
Dim v3 As Long
v3 = v1
v1 = v2
v2 = v3
End Sub

Voila le resultat pour la premiere :

?SwapLng@Module1@@AAGXXZ PROC NEAR
; 16 : Nb1 = Nb1 Xor Nb2

00000 8b 4c 24 08 mov ecx, DWORD PTR _Nb2$[esp-4]
00004 8b 44 24 04 mov eax, DWORD PTR _Nb1$[esp-4]
00008 56 push esi
00009 8b 11 mov edx, DWORD PTR [ecx]
0000b 8b 30 mov esi, DWORD PTR [eax]
0000d 33 f2 xor esi, edx
0000f 89 30 mov DWORD PTR [eax], esi
00011 8b d6 mov edx, esi

; 17 : Nb2 = Nb1 Xor Nb2
00013 8b 31 mov esi, DWORD PTR [ecx]
00015 33 f2 xor esi, edx
00017 89 31 mov DWORD PTR [ecx], esi

; 18 : Nb1 = Nb1 Xor Nb2
00019 8b 10 mov edx, DWORD PTR [eax]
0001b 8b ce mov ecx, esi
0001d 5e pop esi
0001e 33 d1 xor edx, ecx
00020 89 10 mov DWORD PTR [eax], edx

; 19 : End Sub
00022 c2 08 00 ret 8
?SwapLng@Module1@@AAGXXZ ENDP

et le resulta pour la deuxieme :

?Swap@Module1@@AAGXXZ PROC NEAR

; 22 : Dim v3 As Long
; 23 : v3 = v1
; 24 : v1 = v2

00000 8b 54 24 08 mov edx, DWORD PTR _v2$[esp-4]
00004 8b 44 24 04 mov eax, DWORD PTR _v1$[esp-4]
00008 56 push esi
00009 8b 32 mov esi, DWORD PTR [edx]
0000b 8b 08 mov ecx, DWORD PTR [eax]
0000d 89 30 mov DWORD PTR [eax], esi

; 25 : v2 = v3

0000f 89 0a mov DWORD PTR [edx], ecx
00011 5e pop esi

; 26 : End Sub

00012 c2 08 00 ret 8
?Swap@Module1@@AAGXXZ ENDP

C'est tout vue, ceux qui avais des doute n'en on surement plus ;)

@+