Page 3 sur 3

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : sam. 28/févr./2015 21:04
par Kwai chang caine
Et ben si tu as un step minimum de 1, ta variable va s'incrémenter au pas de 1 à chaque passage
Ce qui fait que si toi tu voulais un pas dynamique de 4 par exemple, tu seras obligé de rajouter une ligne ou une opération, retirant le 1 de ta variable d'incrémentation

Exemple

Code : Tout sélectionner

Define.i i, iPAS = 4

For i=1 To 40 Step 1
  Debug i
  i + (iPAS - 1)
Next i
Alors qu'avec le step à Zero, la variable n'est pas "déflorée" et reste donc intacte :mrgreen:
Si tu imposes un step de 4 tu n'auras rien à retirer, donc pas à rajouter le -1 que la boucle venait de rajouter juste avant, pour que tu la retire juste aprés ...en fin de compte un "aller/retour" pour rien, enfin si je peut m'exprimer ainsi :mrgreen:

Exemple 2 de notre ami GallyHC (Dans cet exemple pas de -1 inutile)

Code : Tout sélectionner

Define.i i, iPAS = 4

For i=1 To 40 Step 0
  Debug i
  i + iPAS
Next i
C'est vrai qu'on enc...un peu les mouches dans cet exemple, mais moi aussi ce STEP 0 m'a super botté 8)
C'est rigolo de voir qu'en x années de prog, d'avoir utilisé whatmille fois ce genre de boucles, on ai pas pensé qu'il puisse avoir un zéro à cet endroit 8O
Il a pas de chance ce Zéro, il a pourtant les mêmes droits que les 9 autres chiffres, mais c'est bien souvent qu'on l'oublie :|
Faut dire que selon sa place.....il pese pas lourd :lol:
En fin de compte comme dans toutes les passions, c'est l'effet de surprise qui fait prendre son meilleur panard :mrgreen:

Voila mon canard...j'espere que je suis arrivé à me faire comprendre :oops:
Des fois, la prog c'est comme avec les filles, les choses les plus simples sont pas faciles à expliquer simplement 8O

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : sam. 28/févr./2015 21:47
par SPH
Je crois que j'ai compris. Merci :wink:

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : sam. 28/févr./2015 22:02
par Kwai chang caine
De rien mon grand... j'suis content :wink:
Pour une fois que je suis pas le dernier à comprendre :oops:

Et puis c'est vrai qu'une explication proche "des choses de la vie" peut permettre de mieux comprendre :lol:

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : sam. 28/févr./2015 23:22
par falsam
Pas mal les macros Nico et Papipp :)

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : lun. 02/mars/2015 8:30
par PAPIPP
Bonjour à tous
voici une petite amélioration avec les macros et un peu de ASM pour éviter le contrôle des structures conditionnelles par IDE de purebasic comme :
If
...
else
....
endif
ou
while
....
wend.

Ici comme il y a 2 while il faut pour rétablir l'ordre inverser les wend avec le test sur le pas dans la macro nextd(....) pour obtenir
while .......(1)
while .......(2)
......
wend........(2)
wend........(1°

Code : Tout sélectionner

Macro ford (variable,debut,fin,pas) 
	variable=debut
	zero.D=0.0
		EnableASM
		FLD    qword [v_pas]
		FCOMP  [v_zero]
		FNSTSW ax
		TEST   ah,41h
		JNE   @f
		DisableASM
	While variable <=fin 
	!jmp lab11#MacroExpandedCount
	!@@:
	While variable >= fin 
	!lab11#MacroExpandedCount:
		
EndMacro       
Macro Nextd(Variable,Pas)
					Variable+Pas
;           zero.D=0.0
						EnableASM
						FLD    qword [v_pas]
						FCOMP  [v_zero]
						FNSTSW ax
						TEST   ah,41h
						JE   @f  ; ICI inversion du test par rapport à la macro ford(...) pour avoir le wend correspondant au while 
						DisableASM
		Wend
			!jmp lab12#MacroExpandedCount
			!@@:
		Wend
		!lab12#MacroExpandedCount:
EndMacro

pas.d=4
Ford(a.d,10.0,100.0,pas)
Debug a
Nextd(a,pas)

Debug "---------------------------"
; 
pas=-10.0 
Ford(b.d,200.0,10.0,pas)
Debug b
Nextd(b,pas)

Debug "---------------------------"
pas=-3.4
ford(C.d,#PI,-30*#PI,pas)
Debug c
nextd(C.d,pas)

On doit encore avoir la possibilité d'améliorer ces macros en remplaçant while et wend par leur équivalent en ASM
A+

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : lun. 02/mars/2015 12:02
par nico
Tu pourrais nous montrer la différence entre le code généré par PureBasic et le tiens, ce serait intéressant de voir où se situe l'optimisation au niveau du while.

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : lun. 02/mars/2015 12:56
par PAPIPP
Bonjour nico

J'ai utiliser le code PB suivant pour générer les instructions ASM
code PB utilisé

Code : Tout sélectionner

Macro ForP(Variable,Debut,Fin);,pas)
  variable=debut
  While Variable<=Fin ;And pas >0
  EndMacro
  
  Macro Forn(Variable,Debut,Fin);,pas)
    variable=debut
    While Variable>=Fin ;And pas <0
  EndMacro
      Macro Nextpn(Variable,Pas)
        Variable+Pas
      Wend
    EndMacro
    pas.d=4
    If pas >0
      Debug pas
    EndIf  
Forp(a.d,10.0,100.0)
Debug a
Nextpn(a,pas)

Debug "---------------------------"


Forn(b.d,200.0,10.0)
Debug b
pas=-10.0
Nextpn(b,pas)
Debug "---------------------------"

forn (C.d,#PI,-30*#PI)
Debug c
pas=-3.4
nextpn(C.d,pas)




Code ASM généré par PB

Code : Tout sélectionner

; 
; PureBasic 5.31 (Windows - x86) generated code
; 
; (c) 2014 Fantaisie Software
; 
; The header must remain intact for Re-Assembly
; 
; :System
; KERNEL32
; :Import
; 
format MS COFF
; 
; 
extrn _ExitProcess@4
extrn _GetModuleHandleA@4
extrn _HeapCreate@12
extrn _HeapDestroy@4
extrn _memset
public _PB_Instance
public _PB_ExecutableType
public _PB_OpenGLSubsystem
public _PB_MemoryBase
public PB_Instance
public PB_MemoryBase
public _PB_EndFunctions

macro pb_public symbol
{
  public  _#symbol
  public symbol
_#symbol:
symbol:
}

macro    pb_align value { rb (value-1) - ($-_PB_DataSection + value-1) mod value }
macro pb_bssalign value { rb (value-1) - ($-_PB_BSSSection  + value-1) mod value }

public PureBasicStart
; 
section '.code' code readable executable align 4096
; 
; 
PureBasicStart:
; 
  PUSH   dword I_BSSEnd-I_BSSStart
  PUSH   dword 0
  PUSH   dword I_BSSStart
  CALL  _memset
  ADD    esp,12
  PUSH   dword 0
  CALL  _GetModuleHandleA@4
  MOV    [_PB_Instance],eax
  PUSH   dword 0
  PUSH   dword 4096
  PUSH   dword 0
  CALL  _HeapCreate@12
  MOV    [PB_MemoryBase],eax
; Macro ForP(Variable,Debut,Fin)
; 
; Macro Forn(Variable,Debut,Fin)
; Macro Nextpn(Variable,Pas)
; pas.d=4
  FLD    qword [D1]
  FSTP   qword [v_pas]
; If pas >0
  FLD    qword [v_pas]
  FCOMP  qword [D2]
  FNSTSW ax
  TEST   ah,41h
  JNE   _EndIf2
; Debug pas
; EndIf  
_EndIf2:
; Forp(a.d,10.0,100.0)
  FLD    qword [D3]
  FSTP   qword [v_a]
_While3:
  FLD    qword [v_a]
  FCOMP  qword [D4]
  FNSTSW ax
  TEST   ah,41h
  JE    _Wend3
; Debug a
; Nextpn(a,pas)
  FLD    qword [v_a]
  FADD   qword [v_pas]
  FADD   qword [D2]
  FSTP   qword [v_a]
  JMP   _While3
_Wend3:
; 
; Debug "---------------------------"
; 
; 
; Forn(b.d,200.0,10.0)
  FLD    qword [D5]
  FSTP   qword [v_b]
_While4:
  FLD    qword [v_b]
  FCOMP  qword [D3]
  FNSTSW ax
  TEST   ah,1h
  JNE   _Wend4
; Debug b
; pas=-10.0
  FLD    qword [D6]
  FSTP   qword [v_pas]
; Nextpn(b,pas)
  FLD    qword [v_b]
  FADD   qword [v_pas]
  FADD   qword [D2]
  FSTP   qword [v_b]
  JMP   _While4
_Wend4:
; Debug "---------------------------"
; 
; forn (C.d,#PI,-30*#PI)
  FLD    qword [D7]
  FSTP   qword [v_C]
_While5:
  FLD    qword [v_C]
  FCOMP  qword [D8]
  FNSTSW ax
  TEST   ah,1h
  JNE   _Wend5
; Debug c
; pas=-3.4
  FLD    qword [D9]
  FSTP   qword [v_pas]
; nextpn(C.d,pas)
  FLD    qword [v_C]
  FADD   qword [v_pas]
  FADD   qword [D2]
  FSTP   qword [v_C]
  JMP   _While5
_Wend5:
; 
_PB_EOP_NoValue:
  PUSH   dword 0
_PB_EOP:
  CALL  _PB_EndFunctions
  PUSH   dword [PB_MemoryBase]
  CALL  _HeapDestroy@4
  CALL  _ExitProcess@4
_PB_EndFunctions:
  RET
; 
; 
section '.data' data readable writeable
; 
_PB_DataSection:
_PB_OpenGLSubsystem: db 0
pb_public PB_DEBUGGER_LineNumber
  dd     -1
pb_public PB_DEBUGGER_IncludedFiles
  dd     0
pb_public PB_DEBUGGER_FileName
  db     0
pb_public PB_Compiler_Unicode
  dd     0
pb_public PB_Compiler_Thread
  dd     0
pb_public PB_Compiler_Purifier
  dd     0
pb_public PB_Compiler_Debugger
  dd     0
_PB_ExecutableType: dd 0
align 4
D1: dd 0,1074790400
D2: dd 0,0
D3: dd 0,1076101120
D4: dd 0,1079574528
D5: dd 0,1080623104
D6: dd 0,-1071382528
D7: dd 1413754136,1074340347
D8: dd -1627395514,-1068003365
D9: dd 858993459,-1073007821
align 4
align 4
s_s:
  dd     0
  dd     -1
align 4
; 
section '.bss' readable writeable
_PB_BSSSection:
align 4
; 
I_BSSStart:
_PB_MemoryBase:
PB_MemoryBase: rd 1
_PB_Instance:
PB_Instance: rd 1
; 
align 4
v_a rq 1
v_b rq 1
v_C rq 1
v_pas rq 1
PB_DataPointer rd 1
align 4
align 4
align 4
align 4
I_BSSEnd:
section '.code' code readable executable align 4096
section '.data' data readable writeable
SYS_EndDataSection:

Placer du code ASM dans une macro PB peut poser des pb avec les labels soit banalisés jmp @f avec comme label @@:
ou avec d'autres labels ou il faut changer le label à chaque appel donc utilisation de #MacroExpandedCount dans un label

J'ai un autre pb avec ASM c'est de passer l'adresse de la variable et de l'utiliser avec les instructions FPU (actuellement en étude)

A+

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : mar. 03/mars/2015 0:16
par PAPIPP
Bonjour à tous

voici le code Pb sans variable zero utilisation de FLDZ suivi pour ceux qui veulent m'aider du code ASM généré par PB

Code : Tout sélectionner

Macro ford (variable,debut,fin,pas) 
        variable=debut
        EnableASM
        FLDZ   
	FCOMP  [v_pas]
	FNSTSW ax
	TEST   ah,41h
	JE   @f
	DisableASM
  While variable <=fin 
	!jmp lab11#MacroExpandedCount
	!@@:
  While variable >= fin 
	!lab11#MacroExpandedCount:
				
EndMacro       
Macro Nextd(Variable,Pas)
        Variable+Pas
        EnableASM
        FLDZ    
        FCOMP  [v_pas]
        FNSTSW ax
        TEST   ah,41h
        JNE   @f  ; ICI inversion du test par rapport à la macro ford(...) pour avoir le wend correspondant au while 
        DisableASM
	Wend
	!jmp lab12#MacroExpandedCount
	!@@:
	Wend
	!lab12#MacroExpandedCount:
EndMacro

pas.d=4
Ford(a.d,10.0,100.0,pas)
Debug a
Nextd(a,pas)

Debug "---------------------------"
; 
pas=-10.0 
Ford(b.d,200.0,10.0,pas)
Debug b
Nextd(b,pas)

Debug "---------------------------"
pas=-3.4
ford(C.d,#PI,-30*#PI,pas)
Debug c
nextd(C.d,pas)

Code ASM généré par PB

Code : Tout sélectionner

; PureBasic 5.31 (Windows - x86) generated code
; 
; (c) 2014 Fantaisie Software
; 
; The header must remain intact for Re-Assembly
; 
; :System
; KERNEL32
; :Import
; 
format MS COFF
; 
; 
extrn _ExitProcess@4
extrn _GetModuleHandleA@4
extrn _HeapCreate@12
extrn _HeapDestroy@4
extrn _memset
public _PB_Instance
public _PB_ExecutableType
public _PB_OpenGLSubsystem
public _PB_MemoryBase
public PB_Instance
public PB_MemoryBase
public _PB_EndFunctions

macro pb_public symbol
{
  public  _#symbol
  public symbol
_#symbol:
symbol:
}

macro    pb_align value { rb (value-1) - ($-_PB_DataSection + value-1) mod value }
macro pb_bssalign value { rb (value-1) - ($-_PB_BSSSection  + value-1) mod value }

public PureBasicStart
; 
section '.code' code readable executable align 4096
; 
; 
PureBasicStart:
; 
  PUSH   dword I_BSSEnd-I_BSSStart
  PUSH   dword 0
  PUSH   dword I_BSSStart
  CALL  _memset
  ADD    esp,12
  PUSH   dword 0
  CALL  _GetModuleHandleA@4
  MOV    [_PB_Instance],eax
  PUSH   dword 0
  PUSH   dword 4096
  PUSH   dword 0
  CALL  _HeapCreate@12
  MOV    [PB_MemoryBase],eax
; Macro ford (variable,debut,fin,pas) 
; Macro Nextd(Variable,Pas)
; 
; pas.d=4
  FLD    qword [D1]
  FSTP   qword [v_pas]
; Ford(a.d,10.0,100.0,pas)
  FLD    qword [D2]
  FSTP   qword [v_a]
FLDZ
FCOMP [v_pas]
FNSTSW ax
TEST ah,41h
JE @f
_While1:
  FLD    qword [v_a]
  FCOMP  qword [D3]
  FNSTSW ax
  TEST   ah,41h
  JE    _Wend1
jmp lab111
@@:
_While2:
  FLD    qword [v_a]
  FCOMP  qword [D3]
  FNSTSW ax
  TEST   ah,1h
  JNE   _Wend2
lab111:
; Debug a
; Nextd(a,pas)
  FLD    qword [v_a]
  FADD   qword [v_pas]
  FADD   qword [D4]
  FSTP   qword [v_a]
FLDZ
FCOMP [v_pas]
FNSTSW ax
TEST ah,41h
JNE @f  
  JMP   _While2
_Wend2:
jmp lab121
@@:
  JMP   _While1
_Wend1:
lab121:
; 
; Debug "---------------------------"
; 
; pas=-10.0 
  FLD    qword [D5]
  FSTP   qword [v_pas]
; Ford(b.d,200.0,10.0,pas)
  FLD    qword [D6]
  FSTP   qword [v_b]
FLDZ
FCOMP [v_pas]
FNSTSW ax
TEST ah,41h
JE @f
_While3:
  FLD    qword [v_b]
  FCOMP  qword [D2]
  FNSTSW ax
  TEST   ah,41h
  JE    _Wend3
jmp lab112
@@:
_While4:
  FLD    qword [v_b]
  FCOMP  qword [D2]
  FNSTSW ax
  TEST   ah,1h
  JNE   _Wend4
lab112:
; Debug b
; Nextd(b,pas)
  FLD    qword [v_b]
  FADD   qword [v_pas]
  FADD   qword [D4]
  FSTP   qword [v_b]
FLDZ
FCOMP [v_pas]
FNSTSW ax
TEST ah,41h
JNE @f  
  JMP   _While4
_Wend4:
jmp lab122
@@:
  JMP   _While3
_Wend3:
lab122:
; 
; Debug "---------------------------"
; pas=-3.4
  FLD    qword [D7]
  FSTP   qword [v_pas]
; ford(C.d,#PI,-30*#PI,pas)
  FLD    qword [D8]
  FSTP   qword [v_C]
FLDZ
FCOMP [v_pas]
FNSTSW ax
TEST ah,41h
JE @f
_While5:
  FLD    qword [v_C]
  FCOMP  qword [D9]
  FNSTSW ax
  TEST   ah,41h
  JE    _Wend5
jmp lab113
@@:
_While6:
  FLD    qword [v_C]
  FCOMP  qword [D9]
  FNSTSW ax
  TEST   ah,1h
  JNE   _Wend6
lab113:
; Debug c
; nextd(C.d,pas)
  FLD    qword [v_C]
  FADD   qword [v_pas]
  FADD   qword [D4]
  FSTP   qword [v_C]
FLDZ
FCOMP [v_pas]
FNSTSW ax
TEST ah,41h
JNE @f  
  JMP   _While6
_Wend6:
jmp lab123
@@:
  JMP   _While5
_Wend5:
lab123:
; 
; 
_PB_EOP_NoValue:
  PUSH   dword 0
_PB_EOP:
  CALL  _PB_EndFunctions
  PUSH   dword [PB_MemoryBase]
  CALL  _HeapDestroy@4
  CALL  _ExitProcess@4
_PB_EndFunctions:
  RET
; 
; 
section '.data' data readable writeable
; 
_PB_DataSection:
_PB_OpenGLSubsystem: db 0
pb_public PB_DEBUGGER_LineNumber
  dd     -1
pb_public PB_DEBUGGER_IncludedFiles
  dd     0
pb_public PB_DEBUGGER_FileName
  db     0
pb_public PB_Compiler_Unicode
  dd     0
pb_public PB_Compiler_Thread
  dd     0
pb_public PB_Compiler_Purifier
  dd     0
pb_public PB_Compiler_Debugger
  dd     0
_PB_ExecutableType: dd 0
align 4
D1: dd 0,1074790400
D2: dd 0,1076101120
D3: dd 0,1079574528
D4: dd 0,0
D5: dd 0,-1071382528
D6: dd 0,1080623104
D7: dd 858993459,-1073007821
D8: dd 1413754136,1074340347
D9: dd -1627395514,-1068003365
align 4
align 4
s_s:
  dd     0
  dd     -1
align 4
; 
section '.bss' readable writeable
_PB_BSSSection:
align 4
; 
I_BSSStart:
_PB_MemoryBase:
PB_MemoryBase: rd 1
_PB_Instance:
PB_Instance: rd 1
; 
align 4
v_a rq 1
v_b rq 1
v_C rq 1
v_pas rq 1
PB_DataPointer rd 1
align 4
align 4
align 4
align 4
I_BSSEnd:
section '.code' code readable executable align 4096
section '.data' data readable writeable
SYS_EndDataSection:

A+

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : mer. 04/mars/2015 9:06
par PAPIPP
Bonjour à tous

Voici un exemple simple mais peu élégant pour les puristes de réaliser l'émulation d'un for(...) avec pas variable
avec en plus la possibilité d'utiliser les nombres réels.

La seule restriction est la non possibilité pour l'instant d'avoir des boucles imbriquées.

Code : Tout sélectionner

Macro ford(variable,debut,fin,pas)
  variable=debut
  lab#MacroExpandedCount: ; début de la boucle
   __pas=pas
  If __pas>0
    ;********  	While émulation  variable <=fin  test pas >0  ************
    If variable<=fin
      Goto lab11#MacroExpandedCount
    Else
      Goto Nextd#MacroExpandedCount
    EndIf
  ElseIf __pas<0
    ;********  	While émulation  variable >=fin  test pas <0  ************
    If variable>=fin
      Goto lab11#MacroExpandedCount
    Else
      Goto Nextd#MacroExpandedCount
    EndIf
  ElseIf __pas=0
    MessageRequester("Erreur " , "le pas ne peut être égal à 0") 
    End
  EndIf
  lab11#MacroExpandedCount:
EndMacro
Macro Nextd(Variable)
  Variable+__Pas
  Goto lab#MacroExpandedCount
  Nextd#MacroExpandedCount:
EndMacro

pas.d=4
Ford(a,10.0,100.0,pas)
Debug a
Nextd(a)

Debug "---------------------------"
;
pas=-10.0
Ford(b.d,200.0,10.0,pas)
Debug b
Nextd(b)
; 
Debug "---------------------------"

pas=-3.4
ford(C.d,#PI,-30*#PI,pas)
Debug c
nextd(C.d)

Debug "---------------------------"

pas.d=4
Ford(a,10.0,100.0,pas)
Debug a
Nextd(a)


:;*** teste le pas=0
pas=0
ford(d.d,#PI,-30*#PI,pas)
Debug d
nextd(d.d)

A+

Re: Impossible d'utiliser For..Next avec un step en variable

Publié : sam. 07/mars/2015 14:24
par PAPIPP
Bonjour à tous

Les 2 macros FORD(.....) et NEXTD(.) sont à votre disposition à

http://www.purebasic.fr/french/viewtopi ... =1&t=15106

A+