Définition type entier [Résolu]

Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
- - Dernière réponse : zwyx
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
- 11 janv. 2008 à 10:48
Bonjour à tous,

Je dois étudier des valeurs que je choisis pour l'instant de stocker au format Word. Mais je veux pouvoir un jour à les stocker en Cardinal, sans avoir à remplacer leur définition dans tous le code.

Pour cela, j'ai simplement défini un type:
type
  TValue = Word;

Pour tester la validité d'une de ces valeurs récupérée d'un TEdit quelconque, je faisais avant:
ifStrToInt(ch)>=Low(Word)andStrToInt(ch)<= High(Word)then ...

Maintenant, Low(TValue) ou High(TValue) provoquent à la compilation une erreur d'incompatibilité de types.

Je ne vois pas du tout comment résoudre ce souci pourtant tout bête.

D'avance, merci.
Afficher la suite 

10 réponses

Meilleure réponse
Messages postés
4307
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
3
Merci
type
  TValue = word;

const
  HighTValue = high(TValue);
  LowTValue  = low(TValue);

<hr size="2" width="100%" />
http://deefaze.gnomz.com

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 131 internautes nous ont dit merci ce mois-ci

Commenter la réponse de f0xi
Messages postés
1803
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
7 juillet 2019
3
Merci
Salut,

Je n'ai pas tout lu, mais dès le départ il y a un problème de parenthèses oubliées :

type
  TValue = Word;

Là, ça ne passera jamais :

if StrToInt(ch) >= Low(Word) and StrToInt(ch) <= High(Word) then
  if StrToInt(ch) >= Low(TValue) and StrToInt(ch) <= High(TValue) then

Comme ça, ça compile sans problème :

  if ( StrToInt(ch) > = Low(Word)) and (StrToInt(ch) <= High(Word) ) then

  if (StrToInt(ch) > = Low(TValue)) and (StrToInt(ch) <= High(TValue)) then

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 131 internautes nous ont dit merci ce mois-ci

Commenter la réponse de japee
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
3
Merci
Bon, et bien le problème est résolu. Je suis déçu de m'être fait avoir sur un détail aussi bête.

Le compilateur n'accepte pas que je fasse Low ou High de MonType dans une expression. Mais par contre, je peux le faire dans une commande individuelle. Je m'explique:

// n'est pas accepté
if StrToIntDef(Msg, -1) in [Low(MonType)..High(MonType)] then
...

// est accepté
var
  MinMonType, MaxMonType: MonType;
begin
  MinMonType := Low(MonType);
  MaxMonType := High(MonType);
  if StrToIntDef(Msg, -1) in [MinMonType..MaxMonType] then
    ...

La solution de japee fonctionne également.

Merci à Loda, de m'avoir appris de nouvelles astuces, et à f0xi et japee, pour m'avoir mis sur la voie.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 131 internautes nous ont dit merci ce mois-ci

Commenter la réponse de zwyx
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
0
Merci
salut,

un peu au pif (cad sans avoir fait de test), je dirais que ton problème vient de StrToInt qui return un "integer".

essaie avec StrToInt64.

sinon, un deux conseils:
- TValue est un nom un peu trop commun. ajout un préfix ou nomme ton type autrement. Tu pourrais avoir des conflits de nom par la suite.
- ifStrToInt(ch)>=Low(Word)andStrToInt(ch)<= High(Word)then .
dans ton test, tu fais deux fois la conversion! utilise une var tmp, ou fait une function EstUnNOMTYPEValide():boolean qui aurait la var tmp.

bon code,

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Commenter la réponse de cs_Loda
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
0
Merci
Je l'ai effectivement nommé TSampleValue, et non TValue. J'ai raccourcis dans mon message pour faire abstraction du contexte. Mais c'est vrai que j'aurais pu le nommer TValue y faire plus attention.

Concernant ta deuxième remarque, je ne savais pas qu'allouer une variable temporaire était moins couteux que de faire plusieurs conversions. Mais dans ce cas, j'ai beaucoup de modifications à faire dans mon code.

Le type attribué à TSampleValue sera toujours inférieur ou égal au type Integer, en terme de nombre de bits utilisés. Donc la conversion par StrToInt ne pose pas de problème. Cependant, c'est justement dans l'écriture de ma fonction EstUnSampleValueValide que je souhaite utiliser Low(TSampleValue) et High(TSampleValue). Et là, la compilation échoue. Delphi ne semble vouloir utiliser les fonction Low et High que sur des types de base comme Integer, Cardinal, Byte. Voici comment j'ai écrit cette fonction.

DEFAULT est une constante définie comme égale à -1.

function StrToValDef(Msg: ShortString): Integer;
begin
  if StrToIntDef(Msg, DEFAULT)<Low(TSampleValue) and StrToIntDef(Msg, DEFAULT)>High(TSampleValue) then
    Result := StrToInt(Msg)
  else Result := DEFAULT;
end;
Commenter la réponse de zwyx
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
0
Merci
"Je l'ai effectivement nommé TSampleValue, et non TValue"
parfait.




"Concernant ta deuxième remarque, je ne savais pas qu'allouer une
variable temporaire était moins couteux que de faire plusieurs
conversions" ça dépend des tests. Mais, de manière général les trucs avec des strings.... (note que je n'ai pas fait de mesures pour confirmer mes dires)

au pire, si tu fait une function, tu peux coder en dur le high(word), vu que tu n'aurra à la changer qu'a un endroit.

function StrToValDef(Msg: ShortString): Integer;
begin
  if TryStrToInt(Msg, result) then begin
      if (result > High(word)) OR (result < low(word)) then result := default;
     exit;
  end;
  result := DEFAULT;
end;

note que j'utilise la valeur de retour comme "var tmp"
après, normalement, le compilo devrait mettre ce genre de fct "inline".
-> rapide, sur et facile à utiliser. (le beurre et l'argent du beurre ;-) )

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Commenter la réponse de cs_Loda
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
0
Merci
Très bien, je vais faire comme ça.

Je noterai un gros commentaire à l'endroit où TSampleValue est défini, comme quoi il faut changer aussi dans cette fonction.

Sinon, il faudrait que je redéfinisse les fontions Low et High, mais je ne vois pas trop comment ce serait possible.

Bonne fin de journée Loda.
Commenter la réponse de zwyx
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
0
Merci
En fait, ce que je cherchais à faire, depuis le départ, c'est écrire quelque part que TSampleValue est de tel type entier, et que le compilateur remplace TSampleValue par ce type, partout dans le code. Mais je ne sais pas si c'est possible ?

Mais je ne pense pas me tromper. Pour l'évolution du code après, c'est bien comme ça qu'il faut faire ?
Commenter la réponse de zwyx
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
0
Merci
Mince, je viens de regarder le code. J'avais oublié au fil de notre échange, mais je souhaite déclarer trois types de la même manière que TSampleValue. Il y a également TSampleSize et TNbSample.

J'utilise régulièrement Low et High sur ces trois types, qui sont respectivement définits comme Word, Cardinal et Byte, pour vérifier que les valeurs saisies par l'utilisateur sont correctes.

Le compilateur bloque évidemment à chaque fois pour une incompatibilité de types. Dois-je écrire trois fonctions de type EstDeMonTypeValide ?
Commenter la réponse de zwyx
Messages postés
152
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
21 mars 2016
0
Merci
Bon voilà, j'ai tout changé. J'écris la fonction EstDeMonTypeValide ci-dessous. Par contre, je n'ai pas trouvé la méthode que tu emploies TryStrToInt dans l'aide de mon Delphi 6.

function TForm1.StrToSampleValueDef(Msg: ShortString): Int64;
var
  MinValue, MaxValue: Word;
begin
  MinValue := Low(Word);
  MaxValue := High(Word);
  if StrToIntDef(Msg, DEFAULT) in [MinValue..MaxValue] then
    Result := TSampleValue(StrToInt(Msg))
  else
    Result := DEFAULT;
end;

Du coup, j'imagine que c'est beaucoup plus lent que de travailler directement avec des Word, mais au moins, le code est évolutif.

Cependant, comme l'objectif est de pouvoir traîter rapidement pleins de valeurs, si les performances deviennent catastrophiques, je remettrai tout comme avant, ça aura été utile.

En tout cas, merci de m'avoir aidé Loda, et bonne soirée.
Commenter la réponse de zwyx