Pb pour initialiser un entier Long par un calcul

Résolu
alainc14 Messages postés 12 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 30 mai 2008 - 30 mai 2008 à 15:12
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 - 31 mai 2008 à 00:46
Bonjour,

Chais pas trop quel titre évocateur utiliser pour expliquer le pb :

Dim lngTest as Long
lngTest = 300 * 200
ou n'importe quel calcul dont le résultat est supérieur à la limite des Integer soit 32 767
entraîne le message "erreur d'exec 6. dépassement de capacité"

Autre exemple encore plus tordu :
Dim lngTest as Long, intTest2 as Integer
intTest2 = 300
lngTest = intTest2 * 200
plante également !

Au contraire, les codes suivants ne posent pas de pb :

Dim lngTest as Long
lngTest = 50000 * 200

pas plus que
Dim lngTest as Long, lngTest2 as long
lngTest = 300
lngTest2 = lngTest * 200

ou que
Dim lngTest as Long, intTest2 as Integer
intTest2 = 300
lngTest = intTest2 * 40000

Tout se passe comme si lorsque les facteurs du calcul sont :
- des variables explicitement Integer,
- des valeurs numériques implicitement Integer (<32767) !
il évalue le résultat en Integer avant de le passer à la variable résultat quelque soit son type et donc plante si trop grand

Ce qui est fort, c'est que je ne m'en suis jamais aperçu jusqu'à ce jour ! (et donc peut-être suis en train de découvrir l'eau tiède)

Soit j'ai eu trop de la chance, soit c'est dépendant du hard ?

Qui a 1 mn pour tester ce truc et me dire si ça plante aussi chez lui et pourquoi ?

7 réponses

PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
30 mai 2008 à 15:47
salut

problème :
Dim lngTest as Long
lngTest = 300 * 200

solution :
VB voit 300 et 200
il se dit entier et entier... beh c'est entier (espace de travail)
mais 60000>entier, donc boom

il faut qu'au moins un des 2 soit plus grand

Dim lngTest As Long
lngTest = CLng(300) * 200
long et entier : espace de travail = long. là c'est bon

idem pour
Dim lngTest as Long, intTest2 as Integer
intTest2 = 300
lngTest = intTest2 * 200

entier et entier, çà n'ira pas....

Dim lngTest as Long, intTest2 as Integer
intTest2 = 300
lngTest = intTest2 * 200&

là çà marche ;)

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
3
alainc14 Messages postés 12 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 30 mai 2008
30 mai 2008 à 16:09
J'avais bien diagnostiqué cette histoire !
"il se dit entier et entier... beh c'est entier (espace de travail)"

J'ai toujours pensé : lngTest = ... donc j'alloue un espace de travail pour un Long puisque de toute façon même si le résultat est petit je consommerai 4 octets ...
C'est du gagne petit !
D'autant + fort que généralement MS ne se préoccupe pas trop d'économiser de la mémoire !

C'est assez pervers (et trop laid ...).
Je ne comprends toujours pas comment mes programmes n'ont jamais planté jusqu'à ce jour !
J'ai eu trop de bol !

Tout le monde sait-il ça et je suis un des derniers grands naïfs subsistants ?
Est-ce que le même phénomène survient avec d'autres langages que VB ?
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
30 mai 2008 à 16:27
je sais pas si c'est su mais je sais qu'c'est çà
(jolie allitération non ? :p)

et idem pour dotnet oui, et très logiquement aussi pour d'autres langages....

autant matériellement (supposais-tu), la question ne se pose à ma connaissance que pour les doubles (si ce n'est TOUS les types à 'virgule flottante')
intel contre le reste du monde ^^

nb : le integer étant le plus souvent utilisé pour des incréments ou des calculs simples (+ -), on a rarement le "faux bug", les long/double sont préférés pour les autres calculs

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
alainc14 Messages postés 12 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 30 mai 2008
30 mai 2008 à 16:29
Merci !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
30 mai 2008 à 20:56
Petite précision sur les variables et leur place en mémoire.

VB6 fonctionne sur la plateforme Win32 ou l'unité de base est le 32bit. Toutes les variables déclarées en VB6 dont la taille est inférieure à 32bit occuperont tout de même 32 bits en mémoire. C'est le cas pour le Long, l'Integer, le Byte. C'est une question d'alignement mémoire.
VB6 ne dispose pas de mécanisme d'optimisation comme certains langages plus évolués qui permettrait par exemple de regrouper 4 bytes dans un emplacement mémoire.
C'est totalement transparent pour l'utilisateur dans 99.99% des cas, mais ça peut etre génant dans certains cas de traitements biens particulier.

Pour ce qui est de ton calcul, le fonctionnement est très simple.
VB analyse ta formule, détermine le premier opérande ainsi que son type, il en déduit que ce sera le type du résultat.
Il analyse le second opérande et tente de le convertir au type du premier (et donc du résultat).
Ensuite il fait l'opération et obtient le résultat.

Ce n'est qu'une fois obtenu ce résultat, qu'il analyse le type de la variable devant recevoir ce résultat, tente de convertir ce résultat, et afin attribu cette convertion à la variable.

D'où l'effet de bord que tu viens de rencontrer.

Par exemple :tu dis que lngTest2 lngTest * 200  c'est vrai. Par contre lngTest2 200 * lngTest  ne doit normalement pas marcher, alors que le résultat est strictement le même

---- Sevyc64  (alias Casy) ---- <hr size ="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #    http://aide-office-vba.monforum.com/index.php
0
alainc14 Messages postés 12 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 30 mai 2008
30 mai 2008 à 21:20
C'est violent ce que tu dis Casy.

Du coup, à quoi ça sert d'utiliser des integer ou des byte s'ils occupent autant de memoire qu'un Long ? 

Dans le fond à quoi servent ces types ? ... !
Seules les distinctions Single/Double et Long/Decimal conservent un intérêt.
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
31 mai 2008 à 00:46
salut Casy,
ton exemple est incorrect : VB ne converti pas de gauche à droite mais "au mieux"
lngTest2 = 200 * lngTest  marchera

quant au "pourquoi faire alors", on manque sans doute d'infos.
il serait réducteur (j'espère en tout cas) de penser "types existants par habitude pour les dev".
cependant il me semble bien qu' rt15 s'était amusé à faire certains tests (asm je crois) qui démontraient au final que le byte (par exemple) ne prenait pas vraiment ces 32 bits....

il faudrait des années pour retrouver le sujet   , bien dommage...
si l'un de vous veut tenter de le contacter, il a peut-être encore le lien ;)

++
<hr size ="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
Rejoignez-nous