Bonjour,
Quelle serait pour vous la meilleure solution pour coder dans un WORD une valeur non-signée sur 12 bits complétée par une autre sur 4 bits ?
Le tout pouvant être utilisé dans des tableaux !
Quelle serait votre approche ?
Bonjour,
Quelle serait pour vous la meilleure solution pour coder dans un WORD une valeur non-signée sur 12 bits complétée par une autre sur 4 bits ?
Le tout pouvant être utilisé dans des tableaux !
Quelle serait votre approche ?
Bonjour !
Je ne sais pas si c'est la meilleure solution, mais personnellement j'aurais fait quelque chose comme ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 {$ASSERTIONS ON} type T1 = 0..4095; T2 = 0..15; function Encode(const v1: T1; const v2: T2): word; begin result := (v1 shl 4) or v2; end; procedure Decode(const w: word; out v1: T1; out v2: T2); begin v1 := w shr 4; v2 := w and 15; end; var w: word; v1: T1; v2: T2; begin Assert(%1111111111111111 = 65535); Assert(%111111111111 = 4095); Assert(%1111 = 15); w := Encode(4095, 15); Assert(w = 65535); Decode(w, v1, v2); Assert(v1 = 4095); Assert(v2 = 15); Randomize; v1 := Random(4096); v2 := Random(16); WriteLn(v1); WriteLn(v2); w := Encode(v1, v2); Decode(w, v1, v2); WriteLn(v1); WriteLn(v2); end.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour,
Il existe aussi des enregistrements qui proposent la compression binaire comme cela si je ne fais pas erreur :
Mais je suis loin d'être sûr que c'est pertinent en efficacité comme en lisibilité (le moindre usage demandera des transtypages un peu partout que la solution de Roland masque).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 TStrange = bitpacked record T1 = 0..4095; T2 = 0..15; end;
Salutations.
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)
Pourquoi, il faudrais des transtypages partout, cette affirmation me laisse un peu dubitatif...
je vais faire des essais pour comprendre ta remarque.
Bonjour,
Normalement Pascal est un langage typé et devrait interdire un truc du genre :
et demander :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 var i : Cardinal: // ou Word... Strange : TStrange; //... i := Strange.T1;
A vérifier le degré de tolérance du compilateur FreePascal.
Code : Sélectionner tout - Visualiser dans une fenêtre à part i := Cardinal(Strange.T1);
Il y a aussi la possibilité de déclarer des types TCard12 = 0..4095; et TNibble = 0..15; mais cela ne recule le problème que d'un cran car le reste du programme utilisera certainement d'autre types plus communs.
Sur ce plan, C et C++ paraissent plus souples avec leurs champs binaires typés.
Salutations
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)
Il est possible d'affecter un Byte à un Int64 sans trranstypage, pourquoi pas un sous-ensemble à un Word ? A tester en tout cas.
Autre voie possible, celle des helpers, peut-être plus "naturelle" ?
Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
. Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !
Et quelque chose comme cela ?
Cela ne pourrais pas éviter le transtypages ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 TStrange = bitpacked record case integer of 0: T0: WORD; 1: T1 = 0..4095; T2 = 0..15; end;
Bonsoir,
Voici un test avec les type helpers :
On doit pouvoir tout faire : l'affectation comme un Word, un Encode simultané des 2 parties comme dans l'exemple de Roland, l'affectation différenciée (en clippant ou pas), etc.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 unit Unit1; {$mode objfpc}{$H+} {$MODESWITCH TYPEHELPERS} // indispensable ! interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls; type TDuo = Word; TDuoHelper = type helper(TWordHelper) for TDuo function ToTwelveHighBitsValue: Word; function ToFourLowBitsValue: Word; function SetTwelveHighBitsValue(aValue: Word): Boolean; function SetFourLowBitsValue(aValue: Word): Boolean; end; { TForm1 } TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.frm} { TForm1 } function TDuoHelper.ToTwelveHighBitsValue: Word; begin Result := self shr 4; end; function TDuoHelper.ToFourLowBitsValue: Word; begin Result := self and $F; end; function TDuoHelper.SetTwelveHighBitsValue(aValue: Word): Boolean; begin Result := aValue < $1000; if Result then self := ( self and $F ) or ( aValue shl 4 ); end; function TDuoHelper.SetFourLowBitsValue(aValue: Word): Boolean; begin Result := aValue < $10; if Result then self := ( self and $FFF0 ) or aValue; end; procedure TForm1.Button1Click(Sender: TObject); const cste = $10; var Duo: TDuo; w: Word; begin w := cste; Duo := w; ShowMessage(IntToStr(Duo.ToTwelveHighBitsValue)); Dec(Duo); ShowMessage(IntToStr(Duo.ToFourLowBitsValue)); end; end.
[EDIT] Pour l'approche BitPacked, en lisant ceci, l'utilisation me semble au moins aussi complexe.
Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
. Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !
Ceci fonctionne et je n'ai pas encore vu de désagréments.
Merci a vous pour l'aide apporté...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 TDsTest = bitpacked record case integer of 0: (TOUT: Word); 1: (GRAND: 0..4095; PETIT: 0..15); End;
Bonjour,
Effectivement, pas d'inconvénient apparent (NB : compte tenu de l'ordre de déclaration, le GRAND occupe ici les bits de poids faible du WORD).
Avec cette formule, pas de contrôle du dépassement par un setter : on affecte par exemple Valeur mod 16 au PETIT quand on fait DsTest.PETIT := valeur;, ce qui est le comportement standard de FPC quand on affecte une valeur plus grande à une variable entière non signée.
Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
. Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !
J'ai bien fait ce test la mais le compilateur de veux pas de mon "case" a cette endroits, j'ai un bel "Syntax error, ':' expected but 'CASE' found :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 TDsTest = bitpacked record private case integer of 0: (fTOUT: Word); 1: (fGRAND: 0..4095; fPETIT: 0..15); procedure SetTOUT(AValue: integer); procedure SetGRAND(AValue: integer); procedure SetPETIT(AValue: integer); public property TOUT: word read fTOUT write SetTOUT; property GRAND: 0..4095 read fGRAND write SetGRAND; property PETIT: 0..15 read fPETIT write SetPETIT; End;
Salut
Essayes comme ça :
A+
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 {$MODESWITCH ADVANCEDRECORDS} Type TBigBit = 0..4095; TSmallBit = 0..15; TDsTest = bitpacked record private public procedure Create(Value : Word); overload; procedure Create(Value : TBigBit); overload; procedure Create(Value : TSmallBit); overload; procedure Create(BigValue : TBigBit; SmallValue : TSmallBit); overload; case integer of // Doit-être dans la partie public, sinon il faut declarer dans UNE CLASSE (je crois que ce n'est pas faisable dans un record) un "sous-type" dans private et accéder aux valeurs avec des setter/getter dans les propriétés 0: (TOUT: Word); 1: (GRAND: TBigBit; PETIT: TSmallBit); End; Implementation Procedure Tdstest.Create(Value : Word); Begin Self.Tout := Value; End; Procedure Tdstest.Create(Value : Tbigbit); Begin Self.Grand := Value; End; Procedure Tdstest.Create(Value : Tsmallbit); Begin Self.Petit := Value; End; Procedure Tdstest.Create(Bigvalue : Tbigbit; Smallvalue : Tsmallbit); Begin Self.Grand := BigValue; Self.Petit := SmallValue; End;
- "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
- "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
- "La simplicité est la sophistication suprême" - Léonard De Vinci
- "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei
Mes projets sur Github - Blog - Site DVP
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager