Integer et routines de bas niveau

Résolu
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 - 4 nov. 2009 à 11:08
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 - 4 nov. 2009 à 15:32
Bonjour à tous,

N'étant pas très familiarisé aux routines Delphi de bas niveau, permettez-moi de vous poser la question :
Est-il possible de stocker dans une variable de type Integer deux variables de type SmallInt ?

X et Y sont de type SmallInt.
Les 16 premiers bits de la variable integer = valeur de X
Les 16 derniers = valeur de Y

Merci d'avance

Thierry

10 réponses

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
4 nov. 2009 à 12:05
Salut,

avec des variables de type "Word" ça fonctionne:

[hr]var X,Y: Word;

    Value: Integer;
[b]begin
  /b// fixe les valeurs X & Y
  X:=  1024;
  Y := 768;
   // on les "combines" dans un entier;
  Value : = MakeLong(X,Y);
  // et on les récupères et on les affiches
  Caption := Format('X := %d - Y := %d', [LoWord(Value), HiWord(Value)]);
end;
[hr]

voilà je pense qu'avec ça tu devrais pouvoir faire ce que tu veux
@+Cirec
[hr]
3
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
4 nov. 2009 à 11:51
bonjour,

ex : 24 en décimal
cela donne 11000 en base 2

Mais si tu veux 16 bits cela donne
0000000000011000
déjà là ça ne passe pas en integer alors en smallint..

Il serait préférable de nous dire exactement ce que tu souhaites faire..

cantador
0
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
4 nov. 2009 à 12:17
Oui, de même qu'il est possible de stocker 32 (!) valeurs booléennes dans un Integer. Pas directement, puisque sur les architectures traditionnelles, c'est 1 octet minimum (donc Boolean = 1 octet et non pas 1 bit), mais en codant vite fait un "getter/setter" : pour chaque bit de l'integer, il est à 1 soit à 0. Facile à faire avec des OR pour définir les valeurs, et un AND pour vérifier les valeurs.

Si ça peut aider quelqu'un ... pratique pour gagner de la mémoire sur des environnements restreints.

Cordialement, Bacterius !
0
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
4 nov. 2009 à 13:03
@Cantador : merci pour ton intervention

@Cirec : merci beaucoup, c'est impeccable. J'ai essayé ton code avec des SmallInt:

var
X,Y: smallint;
Value, Z: integer;
begin
X:= -1000;
Y:= 768;
Value := MakeLong(X,Y);
Z:= LoWord(Value);
end;

Resultat: Z 64536 (Limite d'un Word + 1) - 1000
Donc possibilité de retrouver un nombre négatif si Z dépasse la limite d'un smallint.
Mais est-ce bien catholique ?

A +
Thierry
0

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

Posez votre question
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
4 nov. 2009 à 13:10
@Bacterius : oui, ton "getter/setter" m'intéresse.

A +
Thierry
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
4 nov. 2009 à 13:20
oui mais il faut transtyper sinon ça va être pagaille
[hr]var X,Y: SmallInt;

    Value: Integer;
[b]begin
  /b// fixe les valeurs X & Y
  X:=  -1024;
  Y := -768;
   // on les "combines" dans un entier;
  Value : = MakeLong(Word(X),Word(Y));
  // et on les récupères et on les affiches
  Caption := Format('X := %d - Y := %d', [SmallInt(LoWord(Value)), SmallInt(HiWord(Value))]);
end;
[hr]

comme ça ça fonctionne .. j'y avais pas pensé de suite
@+Cirec
[hr]
0
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
4 nov. 2009 à 13:44
Merci pour cette précision.

A +
Thierry
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
4 nov. 2009 à 13:58
pour mettre 32 Booléens dans un entier c'est simple

tu places (pour l'exemple) plusieurs TCheckBox & TRadioButton sur ta fiche et tu leurs donnes à tous un numéro unique (par la propriété Tag) compris entre 0 et 31 et tu complètes comme ceci:
[hr]function Tfrm_Main.GetCheckedComponents : Cardinal;

var I : Integer;
[b]begin
  /bResult :=  0;
   for  I : = 0 to ComponentCount - 1 [b]do
    if /bComponents[I] is TCheckBox [b]then
    begin
      with /bTCheckBox(Components[I]) [b]do
        if /bChecked then Result :=  Result  or  (1 shl Tag);
    [b]end
    else
    if /bComponents[I] is TRadioButton [b]then
    begin
      with /bTRadioButton(Components[I]) [b]do
        if /bChecked then Result : = Result or (1 shl Tag);
    end;
end;

procedure Tfrm_Main.SetCheckedComponents(Value : Cardinal);
var I : Integer;
[b]begin
  for /bI :=  0  to  ComponentCount - 1 [b]do
    if /bComponents[I] is TCheckBox [b]then
    begin
      with /bTCheckBox(Components[I]) [b]do
        /bChecked : = (Value and (1 shl Tag)) > 0 ;
    [b]end
    else
    if /bComponents[I] is TRadioButton [b]then
    begin
      with /bTRadioButton(Components[I]) [b]do
        /bChecked := (Value and (1 shl Tag)) > 0 ;
    [b]end
end/b;
[hr]
avec ce code tu peux enregistrer/récupérer l'état de 32 valeurs booléen dans un seul entier

@+Cirec
[hr]
0
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
4 nov. 2009 à 15:17
Re-bonjour Cirec,

Merci pour ce "tuto" sur shl.

MakeLong correspond donc à :
Value:= X or (Y shl 16);

Retrouver la valeur de X :
X: = Word(Value); // on ne lit que les 16 premiers bits.
Y:= Word(Value shr 16); // on lit les 16 suivants.

Ai-je bien tout compris, cher prof ?

Encore merci, Cirec

Thierry
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
4 nov. 2009 à 15:32
oui c'est ça

d'ailleurs tu peux voir les implémentations de "MakeLong" & "HiWord" dans l'unité Windows.pas


[hr]@+Cirec
[hr]
0
Rejoignez-nous