Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Blocage boucle FOR NEXT en SINGLE

21 réponses
Avatar
Papyjac
Bonjour,

Je suis en version V2003

J'exécute le code simple suivant :

Sub TestSingle()
'_Appel de la fonction
Call TestBoucle(1000000#)
Call TestBoucle(10000000#)
Call TestBoucle(100000000#)
End Sub

Private Sub TestBoucle(Max As Single)
'_Boucle de traitement
Dim U_I As Single ' Indice
For U_I = 1 To Max Step 1
Next
MsgBox Max & " boucles effectuées"
End Sub

La 1ère et la 2ème boucle sont correcte
La 3ème boucle se bloque sur le NEXT avec U_I= 1,677722E+07

Il ne s'agit pas d'un plantage, mais d'un blocage

Bon, ce code ne sert à rien, mais c'est pas une raison pour bloquer

C'est un problème connu ?

--
Papyjac

10 réponses

1 2 3
Avatar
Thom
Bonjour,

En effet, je ne suis pas certain que ta syntaxe fonctionne en VBA.

Lors de mon test, j'ai mis sur pause(CTRL+PAUSE) l'exécution du programme
pour contrôler la valeur de la variable et continuer l'exécution en pas à
pas. J'ai pu constaté que passé le seuil des 1,677722E+07, la variable ne
s'incrémente plus(sans message d'erreur), et que la boucle continue à
tourner.

Cordialement,

Thomas


"Jacques-A" a écrit dans le message
de news:
Thom a écrit :
Bonjour Mousnynao,
Dans mes tests, j'ai simplifié au maximun en faisant :

Public Sub Test()
Dim i as Single
For i = 0 to 100000000
Next
End Sub

... et ça ne fonctionne pas non plus
:-(

"Mousnynao" a écrit dans le message
de news:
Bonjour,

À mon humble avis :

L'utilisation du mot réservé MAX est douteux !

Private Sub TestBoucle(Max As Single)

Pourraît faire apparaître des comportements fantomatique !

mousnynao

"Papyjac" a écrit :

Bonjour Thom,

Et merci de me confirmer que je ne suis pas fou

J'ai aussi testé en DOUBLE : c'est OK

Mystère

--
Papyjac


"Thom" a écrit :

Bonjour,

Je confirme le "blocage", je n'ai pas de plantage, mais le text
n'arrive pas
à paser les
1,677722E+07 et non les 3,402823E38 promis dans les spécifications VBA

Parcontre, j'ai fait l'essai avec une variable long ou variant, il n'y
a pas
de soucis.

J'ai aussi fait la conversion de 100000001 en single et là aussi ça
passe...
Etrange

Thomas


"Papyjac" a écrit dans le message
de
news:
Bonjour,

Je suis en version V2003

J'exécute le code simple suivant :

Sub TestSingle()
'_Appel de la fonction
Call TestBoucle(1000000#)
Call TestBoucle(10000000#)
Call TestBoucle(100000000#)
End Sub

Private Sub TestBoucle(Max As Single)
'_Boucle de traitement
Dim U_I As Single ' Indice
For U_I = 1 To Max Step 1
Next
MsgBox Max & " boucles effectuées"
End Sub

La 1ère et la 2ème boucle sont correcte
La 3ème boucle se bloque sur le NEXT avec U_I= 1,677722E+07

Il ne s'agit pas d'un plantage, mais d'un blocage

Bon, ce code ne sert à rien, mais c'est pas une raison pour bloquer

C'est un problème connu ?

--
Papyjac














Bonjour,

Avez-vous tenté de vérifier durant la boucle (attention, je ne suis pas
certain de ne pas avoir mélanger les langages) ?

dim I As Single
M000
K=M
for i= K to 100E6
M = M+1
if i .NE. M print "Déraillement : " i " diffère de " m
next


Jacques


Avatar
Jacques-A
Thom a écrit :
Bonjour,

En effet, je ne suis pas certain que ta syntaxe fonctionne en VBA.


C'est bien pourquoi j'ai attiré l'attention sur ce fait. Mais l'idée de
faire croitre une seconde variable qui doit rester identique et imprimer
un diagnostic lors de la divergence ?

Jacques

Lors de mon test, j'ai mis sur pause(CTRL+PAUSE) l'exécution du programme
pour contrôler la valeur de la variable et continuer l'exécution en pas à
pas. J'ai pu constaté que passé le seuil des 1,677722E+07, la variable ne
s'incrémente plus(sans message d'erreur), et que la boucle continue à
tourner.

Cordialement,

Thomas


"Jacques-A" a écrit dans le message
de news:
Thom a écrit :
Bonjour Mousnynao,
Dans mes tests, j'ai simplifié au maximun en faisant :

Public Sub Test()
Dim i as Single
For i = 0 to 100000000
Next
End Sub

... et ça ne fonctionne pas non plus
:-(

"Mousnynao" a écrit dans le message
de news:
Bonjour,

À mon humble avis :

L'utilisation du mot réservé MAX est douteux !

Private Sub TestBoucle(Max As Single)

Pourraît faire apparaître des comportements fantomatique !

mousnynao

"Papyjac" a écrit :

Bonjour Thom,

Et merci de me confirmer que je ne suis pas fou

J'ai aussi testé en DOUBLE : c'est OK

Mystère

--
Papyjac


"Thom" a écrit :

Bonjour,

Je confirme le "blocage", je n'ai pas de plantage, mais le text
n'arrive pas
à paser les
1,677722E+07 et non les 3,402823E38 promis dans les spécifications VBA

Parcontre, j'ai fait l'essai avec une variable long ou variant, il n'y
a pas
de soucis.

J'ai aussi fait la conversion de 100000001 en single et là aussi ça
passe...
Etrange

Thomas


"Papyjac" a écrit dans le message
de
news:
Bonjour,

Je suis en version V2003

J'exécute le code simple suivant :

Sub TestSingle()
'_Appel de la fonction
Call TestBoucle(1000000#)
Call TestBoucle(10000000#)
Call TestBoucle(100000000#)
End Sub

Private Sub TestBoucle(Max As Single)
'_Boucle de traitement
Dim U_I As Single ' Indice
For U_I = 1 To Max Step 1
Next
MsgBox Max & " boucles effectuées"
End Sub

La 1ère et la 2ème boucle sont correcte
La 3ème boucle se bloque sur le NEXT avec U_I= 1,677722E+07

Il ne s'agit pas d'un plantage, mais d'un blocage

Bon, ce code ne sert à rien, mais c'est pas une raison pour bloquer

C'est un problème connu ?

--
Papyjac












Bonjour,

Avez-vous tenté de vérifier durant la boucle (attention, je ne suis pas
certain de ne pas avoir mélanger les langages) ?

dim I As Single
M000
K=M
for i= K to 100E6
M = M+1
if i .NE. M print "Déraillement : " i " diffère de " m
next


Jacques






Avatar
Jacques-A
Thom a écrit :
Bonjour,


Re,

En effet, je ne suis pas certain que ta syntaxe fonctionne en VBA.

Lors de mon test, j'ai mis sur pause(CTRL+PAUSE) l'exécution du programme
pour contrôler la valeur de la variable et continuer l'exécution en pas à
pas. J'ai pu constaté que passé le seuil des 1,677722E+07, la variable ne
s'incrémente plus(sans message d'erreur), et que la boucle continue à
tourner.


Je suis surpris de la valeur 0x1000004 qui n'est pas logique. Elle
devrait plutôt être un chiffre rond en hexa (0x1000000 ou même FF FFFF)
ou, pour dire autrement 24 bits à 1.

Peut-être faut-il refaire le test avec un affichage en hexa sur le fin
de la boucle ?

Dim i as single
for i = 0xFFFFFA to 0x1000004
print i ' using format hexa serait mieux
next


Jacques
Avatar
bcar
Bonjour,

Le type single (comme le type double) ne représente pas tous les réels
dans le range compris entre -3,402823E38 et 3,402823E38.

En fait 16777217 n'est pas représentable par un Single, on utilise un
nombre approché, malheureusement pour toi, ce nombre est 16777216

Autrement dit avec des single ou des double tu peux très bien avoir
Dim s1 as single, s2 as single
s1 = ...
s2 = s1 + 1

et s1 - s2 = 0 ou s1 - S2 = 1

C'est pourquoi il est recommandé de faire très attention quand on
manipule ce genre de type de données.

Je te conseille de regarder comment est représenté un nombre réel en
informatique : Signe, Exposant, Mantisse.

Papyjac a écrit :
Bonjour,

Je suis en version V2003

J'exécute le code simple suivant :

Sub TestSingle()
'_Appel de la fonction
Call TestBoucle(1000000#)
Call TestBoucle(10000000#)
Call TestBoucle(100000000#)
End Sub

Private Sub TestBoucle(Max As Single)
'_Boucle de traitement
Dim U_I As Single ' Indice
For U_I = 1 To Max Step 1
Next
MsgBox Max & " boucles effectuées"
End Sub

La 1ère et la 2ème boucle sont correcte
La 3ème boucle se bloque sur le NEXT avec U_I= 1,677722E+07

Il ne s'agit pas d'un plantage, mais d'un blocage

Bon, ce code ne sert à rien, mais c'est pas une raison pour bloquer

C'est un problème connu ?



Avatar
Thom
C'est assez bien vu : voici le résultat du test avec une conversion en Long
et en Hexa
[...]
Long 16777215 > Hex FFFFFF *** Fonctionne
Long 16777216 > Hex 1000000 *** Plantage ***

Dans l'aide VBA, il est précisé que le compteur de l'instruction "For...
Next" ne gère pas les variables de type Boolean et les tableaux, je crois
qu'il faut rajouter à la liste les variable de type Single de plus de 3
octets



"Jacques-A" a écrit dans le message
de news:
Thom a écrit :
Bonjour,


Re,

En effet, je ne suis pas certain que ta syntaxe fonctionne en VBA.

Lors de mon test, j'ai mis sur pause(CTRL+PAUSE) l'exécution du programme
pour contrôler la valeur de la variable et continuer l'exécution en pas à
pas. J'ai pu constaté que passé le seuil des 1,677722E+07, la variable ne
s'incrémente plus(sans message d'erreur), et que la boucle continue à
tourner.


Je suis surpris de la valeur 0x1000004 qui n'est pas logique. Elle devrait
plutôt être un chiffre rond en hexa (0x1000000 ou même FF FFFF) ou, pour
dire autrement 24 bits à 1.

Peut-être faut-il refaire le test avec un affichage en hexa sur le fin de
la boucle ?

Dim i as single
for i = 0xFFFFFA to 0x1000004
print i ' using format hexa serait mieux
next


Jacques


Avatar
bcar
Re-Bonjour,

pour un peu plus de précisions :

- la mantisse de 16777216 s'écrit 1000000000000000000000000 (25 bits)
alors que la mantisse d'un single ne possède que 23 bits donc on ne
conserve que les 23 bits de gauche (+1 car le premier est forcement 1
donc on l'omet dans la mantisse) et on obtient 00000000000000000000000
0 pour le bit de signe
24 pour l'exposant auquel on ajoute 127 ce qui donne 10010111
et on a donc le nombre suivant
0 10010111 00000000000000000000000

- la mantisse de 16777217 s'écrit 1000000000000000000000001 (25 bits )
...
=> 0 10010111 00000000000000000000000
donc égal à 16777216

- la mantisse de 16777218 s'écrit 1000000000000000000000010 (25 bits)
...
=> 0 10010111 00000000000000000000001
donc différent de 1677216

bcar a écrit :
Bonjour,

Le type single (comme le type double) ne représente pas tous les réels
dans le range compris entre -3,402823E38 et 3,402823E38.

En fait 16777217 n'est pas représentable par un Single, on utilise un
nombre approché, malheureusement pour toi, ce nombre est 16777216

Autrement dit avec des single ou des double tu peux très bien avoir
Dim s1 as single, s2 as single
s1 = ...
s2 = s1 + 1

et s1 - s2 = 0 ou s1 - S2 = 1

C'est pourquoi il est recommandé de faire très attention quand on
manipule ce genre de type de données.

Je te conseille de regarder comment est représenté un nombre réel en
informatique : Signe, Exposant, Mantisse.

Papyjac a écrit :
Bonjour,

Je suis en version V2003

J'exécute le code simple suivant :

Sub TestSingle()
'_Appel de la fonction
Call TestBoucle(1000000#)
Call TestBoucle(10000000#)
Call TestBoucle(100000000#)
End Sub

Private Sub TestBoucle(Max As Single)
'_Boucle de traitement
Dim U_I As Single ' Indice
For U_I = 1 To Max Step 1
Next
MsgBox Max & " boucles effectuées"
End Sub

La 1ère et la 2ème boucle sont correcte
La 3ème boucle se bloque sur le NEXT avec U_I= 1,677722E+07

Il ne s'agit pas d'un plantage, mais d'un blocage

Bon, ce code ne sert à rien, mais c'est pas une raison pour bloquer

C'est un problème connu ?





Avatar
Jacques-A
Thom a écrit :
C'est assez bien vu : voici le résultat du test avec une conversion en Long
et en Hexa
[...]
Long 16777215 > Hex FFFFFF *** Fonctionne
Long 16777216 > Hex 1000000 *** Plantage ***

Dans l'aide VBA, il est précisé que le compteur de l'instruction "For...
Next" ne gère pas les variables de type Boolean et les tableaux, je crois
qu'il faut rajouter à la liste les variable de type Single de plus de 3
octets




Bonsoir,

Je pense que c'est peut-être dans l'aide pour les types de variables. Si
on y trouve que le type single est défini sur 24 bits, la limite me
semble évidente. La question reste entière pour les valeurs négatives
(mais je ne sais plus si le VBA Excel accepte les boucles décroissantes,
j'en suis resté à la bonne vieille programmation "macro" ;-) ).

Autrement, je doute qu'on arrive à faire changer l'aide VBA (sauf si
l'un des développeurs lit ce forum). Par contre, je pense que le(la)
gestionnaire de la FAQ Excel francophone est peut-être sur le forum et
qu'il(elle) verra ce fil.

A+

Jacques
Avatar
bcar
Bonjour,

Pourquoi changer l'aide vba ?
L'utilisateur doit bien être être conscient que dans le range couvert
par les single / double, tous les entiers ne sont pas définis.

Dans le cas décrit ici, ce n'est pas un plantage, mais une mauvaise
utilisation des types flottant.

Toujours dans le cas présent tu aurais pu avoir (je déconseille
fortement, mais bon peut être que cela peut servir dans certains cas)
FOR i = vmin TO vmax STEP x
...
if i >= ... then x = x + 1
...
next i


Jacques-A a écrit :
Thom a écrit :
C'est assez bien vu : voici le résultat du test avec une conversion
en Long et en Hexa
[...]
Long 16777215 > Hex FFFFFF *** Fonctionne
Long 16777216 > Hex 1000000 *** Plantage ***

Dans l'aide VBA, il est précisé que le compteur de l'instruction
"For... Next" ne gère pas les variables de type Boolean et les
tableaux, je crois qu'il faut rajouter à la liste les variable de type
Single de plus de 3 octets




Bonsoir,

Je pense que c'est peut-être dans l'aide pour les types de variables. Si
on y trouve que le type single est défini sur 24 bits, la limite me
semble évidente. La question reste entière pour les valeurs négatives
(mais je ne sais plus si le VBA Excel accepte les boucles décroissantes,
j'en suis resté à la bonne vieille programmation "macro" ;-) ).

Autrement, je doute qu'on arrive à faire changer l'aide VBA (sauf si
l'un des développeurs lit ce forum). Par contre, je pense que le(la)
gestionnaire de la FAQ Excel francophone est peut-être sur le forum et
qu'il(elle) verra ce fil.

A+

Jacques


Avatar
Jacques-A
bcar a écrit :
Bonjour,

Pourquoi changer l'aide vba ?
L'utilisateur doit bien être être conscient que dans le range couvert
par les single / double, tous les entiers ne sont pas définis.

Dans le cas décrit ici, ce n'est pas un plantage, mais une mauvaise
utilisation des types flottant.



Parce que le message auquel je répondais disait:
Dans l'aide VBA, il est précisé que le compteur de l'instruction "For...
Next" ne gère pas les variables de type Boolean et les tableaux, je crois
qu'il faut rajouter à la liste les variable de type Single de plus de 3
octets



et que, par principe, une aide est présente pour aider celui qui a un
problème et qu'il pourrait donc être utile de signaler dans le § sur les
boucles que l'usage de flottants de valeur importante peut conduire à
des résultats anormaux lorsque le pas d'incrément devient inférieur à la
précision du compteur.
Cela dissuaderait aussi celui qui voudrait faire une boucle avec un
incrément trop petit (for i=a to b step epsilon)

Je n'en disais pas plus.

Jacques
Avatar
Papyjac
Bonjour bacr, jacquouille, michdenis, thom, mousnynao

Un grand merci pour cette passion et ces explications,

Si c'est pas hasard, que je suis tombé sur ce blocage, sachez que cela n'a
pas entammé ma confiance envers le produit, car effectivement, c'est une
configuration que je n'utilises jamais, mais je pensais que cela pouvais vous
intéresser

Ma recherche actuelle concerne les mesure de performance de certaines
instructions avant de me lancer dans le calcul sur les grands nombres, par
exemple 30000 chiffres significatifs... sans mantisse, ni exposant bien sur
puisque on doit toujours 1+1 = 2 depuis 0, jusqu'à
9999999999999....999999999999999999 (30000 chiffres 9)

Encore merci pour vos réponses
--
Papyjac


"bcar" a écrit :

Re-Bonjour,

pour un peu plus de précisions :

- la mantisse de 16777216 s'écrit 1000000000000000000000000 (25 bits)
alors que la mantisse d'un single ne possède que 23 bits donc on ne
conserve que les 23 bits de gauche (+1 car le premier est forcement 1
donc on l'omet dans la mantisse) et on obtient 00000000000000000000000
0 pour le bit de signe
24 pour l'exposant auquel on ajoute 127 ce qui donne 10010111
et on a donc le nombre suivant
0 10010111 00000000000000000000000

- la mantisse de 16777217 s'écrit 1000000000000000000000001 (25 bits )
....
=> 0 10010111 00000000000000000000000
donc égal à 16777216

- la mantisse de 16777218 s'écrit 1000000000000000000000010 (25 bits)
....
=> 0 10010111 00000000000000000000001
donc différent de 1677216

bcar a écrit :
> Bonjour,
>
> Le type single (comme le type double) ne représente pas tous les réels
> dans le range compris entre -3,402823E38 et 3,402823E38.
>
> En fait 16777217 n'est pas représentable par un Single, on utilise un
> nombre approché, malheureusement pour toi, ce nombre est 16777216
>
> Autrement dit avec des single ou des double tu peux très bien avoir
> Dim s1 as single, s2 as single
> s1 = ...
> s2 = s1 + 1
>
> et s1 - s2 = 0 ou s1 - S2 = 1
>
> C'est pourquoi il est recommandé de faire très attention quand on
> manipule ce genre de type de données.
>
> Je te conseille de regarder comment est représenté un nombre réel en
> informatique : Signe, Exposant, Mantisse.
>
> Papyjac a écrit :
>> Bonjour,
>>
>> Je suis en version V2003
>>
>> J'exécute le code simple suivant :
>>
>> Sub TestSingle()
>> '_Appel de la fonction
>> Call TestBoucle(1000000#)
>> Call TestBoucle(10000000#)
>> Call TestBoucle(100000000#)
>> End Sub
>>
>> Private Sub TestBoucle(Max As Single)
>> '_Boucle de traitement
>> Dim U_I As Single ' Indice
>> For U_I = 1 To Max Step 1
>> Next
>> MsgBox Max & " boucles effectuées"
>> End Sub
>>
>> La 1ère et la 2ème boucle sont correcte
>> La 3ème boucle se bloque sur le NEXT avec U_I= 1,677722E+07
>>
>> Il ne s'agit pas d'un plantage, mais d'un blocage
>>
>> Bon, ce code ne sert à rien, mais c'est pas une raison pour bloquer
>>
>> C'est un problème connu ?
>>



1 2 3