[delphi] Kan geen 3 bytes alloceren?

Pagina: 1
Acties:
  • 107 views sinds 30-01-2008
  • Reageer

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik wilde mijn datumvelden in een class wat compacter maken, omdat er een behoorlijke hoeveelheid instanties van die class kunnen onstaan (zit data in t.b.v. een treeview). Ik gebruik op dit moment TDateTime. Die is 64 bits en dat is natuurlijk veel meer dan noodzakelijk. Om de een of andere reden is TDate ook 64 bits, dus daar ben ik ook niet mee geholpen.

Dus ik dacht, dan zelf maar een record in elkaar knutselen :)
Delphi:
1
2
3
4
5
TCompactDate = packed record
   Day: 1..31;
   Month: 1..12;
   Year: 0..9999;
end;
Prima, hierbij gebruiken Day en Month allebij netjes 1 byte, en Year gebruikt 2 bytes (ik kan er dus net zo goed respectievelijk twee bytes en een word van maken). Ik ben achter die informatie gekomen met de SizeOf functie, maar het gekke is dat SizeOf(TCompactDate) geeft 4 terug, dus 32 bits!

En nu komt het... een type als deze:
Delphi:
1
Test = 0..200000;
...daarvan zou je verwachten dat ie 3 bytes beslaat, maar dat gaat kennelijk niet, want SizeOf(Test) geeft dan doodleuk 4 terug.

En nu de hamvraag (kun je een plakje ham komen afhalen als je em beantwoord :P): Hoe krijg ik delphi zover dat ie 3 bytes gebruikt voor mijn TCompactDate?

[ Voor 6% gewijzigd door _Thanatos_ op 18-03-2004 21:46 ]

日本!🎌


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 21-02 23:50
ik denk dat ie het lekker vind om per 32 bits datastructuren te beheren. Is wel zo makkelijk niet? Aangezien je computertje ook 32 bits is.

Pure speculatie, ok, geef ik toe. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Maar waarom is een array van 3 bytes dan wel 3 bytes?

Ik heb het net trouwens nog ff na zitten rekenen, maar mijn TCompactDate moet in extact 22 bits passen, dus 3 bytes met nog 2 bits over...

日本!🎌


  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Misschien dit?

Delphi:
1
2
3
4
5
TCompactDate = packed record
   Day: 1..31;
   Month: 1..12;
   Year: Byte[0..2];
end;


Moet je alleen Year casten naar hetgeen je wil hebben :)

(edit)
Wat Grijze vos zegt is denk ik waar. Delphi werkt intern denk ik met 32-bits omdat dat nou eenmaal mooi in een Integer past.

[ Voor 27% gewijzigd door martijn_brinkers op 18-03-2004 21:52 ]


  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Ik heb het net trouwens nog ff na zitten rekenen, maar mijn TCompactDate moet in extact 22 bits passen, dus 3 bytes met nog 2 bits over...
Waarom maak je er dan geen Byte[0..2] van en maak je een struct die je alleen maar gebruikt om te 'casten' van Byte[0..2] naar je struct. Maw maak een functie die een struct terug geeft en als param een Byte[0..2] heeft.

  • mjax
  • Registratie: September 2000
  • Laatst online: 14-05 11:00
Grijze Vos schreef op 18 maart 2004 @ 21:47:
ik denk dat ie het lekker vind om per 32 bits datastructuren te beheren. Is wel zo makkelijk niet? Aangezien je computertje ook 32 bits is.

Pure speculatie, ok, geef ik toe. ;)
Hier heeft het inderdaad mee te maken. Delphi rond alle types af op 2-byte hoeveelheden. Met "packed" zorg je er alleen voor dat de variabelen van het record "aligned" worden op non-4-byte posities. Zonder packed kan er dus inderdaad loze ruimte ontstaan als er een aantal 2-byte types achter elkaar in je record staan (2 byte loze ruimte na een 2-byte type om precies te zijn), omdat het het meest efficient (voor de CPU) is om alle variabelen op 4-bytes te alignen.

Wat ik niet weet is hoe Delphi omgaat met bijvoorbeeld:

aType = array[0..2] of byte;

Wat is de sizeof() hiervan? Misschien kun je nl. op deze manier een 3 byte record maken. Je zou dan verlost kunnen zijn van de loze bytes BINNEN je record, maar tussen 2 opeenvolgende records zal toch weer minimaal 1 byte ruimte ontstaan, omdat records altijd op 4-bytes aligned worden.

Ik hoop dat je hier iets aan hebt.

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Die arrays zijn idd 3 bytes volgens SizeOf.
Maar het komt er dus op neer dat als ik drie van die arrays achter elkaar zou gebruiken, dat dat nog steeds 96 bits inneemt? Ook als ik de {$A-} compiler directive gebruik?

日本!🎌


  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Maar stel nou dat je het volgende gebruikt (niet geteste code)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type

  TCompactDate = packed record
     Day: 1..31;
     Month: 1..12;
     Year: 0..9999;
  end;

  TCompactDateMem = Byte[0..2];

function GetDate( const DateMem : TCompactDateMem ) : TCompactDate;
begin
  // converteer de 3 bytes naar een TCompactDate
end;

function GetDateMem( const CompactDate : TCompactDate ) : TCompactDateMem;
begin
  // converteer de TCompactDate naar 3 Bytes
end;


Je gebruikt dan maar 3 bytes voor opslag. Natuurlijk moet je hieromheen een mooie class maken maar het gaat om het principe.

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Maar ik hoorde net dat de compiler de fields op 32 bits uitlijnt, dus na elke drie bytes toch weer een byte extra, en dan de volgende drie bytes, enz. En als ik dus meerdere van die datums achter elkaar zet, dan nemen ze dus individueel wel 24 bits in, maar door die uitlijning dus effectief 32 bits... dat is eigenlijk een beetje het probleem dan.

Ja, ik kan wel een array van 9 of 12 of 15 bytes maken, maar erg netjes is dat niet he :)

日本!🎌


Verwijderd

Ik snap niet waarom je je datum objecten van 64 bits terug zou willen brengen naar 24 bits. Het is niet alsof je daarmee erg veel geheugenruimte uitspaart.

Ok, stel dat 't je lukt 't geheel een whopping 5 bytes per object te verkleinen. Stel dat je 1.000.000 objecten hebt (lijkt me wat veel, maargoed, ter illustratie), dan heb je jezelf dus zojuist wel 5 meg gespaard.

Maar is dat nu wel zo veel? Hoe relevant is die 5 meg voor 1.000.000 objecten zelf als alleen al pointers naar zo veel objecten 4 meg in beslag neemt? Om nog maar niet eens te beginnen over de overhead van je dynamic memory allocator (geloof dat dat in Pascal/Delphi terminologie de "heap allocator" heet). En hoeveel van je systeemgeheugen is het?

Verder zit je vervolgens met het probleem dat je je data telkens moet gaan zitten converteren, wat weer extra overhead geeft (code size *en* snelheidsverlies) en gegarandeerd extra bugs oplevert.

Kortom: dit soort optimalisaties zijn totaal niet interessant, of in ieder geval niet voor de gemiddelde thuisgebruiker.

  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Volgens mij zit het net anders. Delphi gebruikt voor 0..999 een integer (dus 32 bits hoewel het ook in 3 byes past). Het betekend niet dat alles aligned wordt op 32 bits boundaries. De output van het volgende progje laat zien dat A,B en C precies na elkaar ge-alloceerd zijn en dat er geen loze ruimte tussen zit

Delphi:
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
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TMyArray = array[0..2] of Byte;

  TMyClass = packed record
    MyArray : TMyArray;
  end;

  TMyBigArray = array[0..2] of TMyClass;


  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  A : TMyClass;
  B : TMyClass;
  C : TMyClass;
begin
  ShowMessage( 'A: ' + IntToStr( Integer( @A ) ) + #13#10 +
    'B: ' + IntToStr( Integer( @B ) )  + #13#10 +
    'C: ' + IntToStr( Integer( @C ) ));

end;

end.
Ja, ik kan wel een array van 9 of 12 of 15 bytes maken, maar erg netjes is dat niet he
Kijk als je geheugen wil besparen zal je iets moeten. Je kan het dus wel netjes maken. Het is zeker geen exotische methode om je eigen geheugen te beheren om zodoende geheugen te besparen.

[ Voor 14% gewijzigd door martijn_brinkers op 18-03-2004 23:08 ]


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik snap niet waarom je je datum objecten van 64 bits terug zou willen brengen naar 24 bits. Het is niet alsof je daarmee erg veel geheugenruimte uitspaart.
Het verschil tussen een 2,8GHz en 3,0GHz is ook niet interessant, maar toch is men eerder geneigd een 3,0 te kopen. Je kan ook gewoon zeggen "alle beetjes helpen". Overigens procentueel is het wel veel. 64->24 bits is een winst van 62,5%. En daarbij zijn de benodigde conversies ook weer niet zoooo spannend.
Hoe relevant is die 5 meg voor 1.000.000 objecten zelf als alleen al pointers naar zo veel objecten 4 meg in beslag neemt?
Op 1M objecten bespaar ik geen 5MB, maar 15MB. tegenover 4MB is dat wel veel. En of een applicatie nou 100MB of 85MB gebruikt... sja, het kan net dat ene verschil zijn dat de app niet laat crashen met een EOutOfMemory ;)

/edit
ohja, daar ging dit topic niet echt over he... het ging om 3 bytes te alloceren, en dat kan met een array dus :)

[ Voor 10% gewijzigd door _Thanatos_ op 18-03-2004 23:20 ]

日本!🎌


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

mjax schreef op 18 maart 2004 @ 21:55:

Hier heeft het inderdaad mee te maken. Delphi rond alle types af op 2-byte hoeveelheden. Met "packed" zorg je er alleen voor dat de variabelen van het record "aligned" worden op non-4-byte posities. Zonder packed kan er dus inderdaad loze ruimte ontstaan als er een aantal 2-byte types achter elkaar in je record staan (2 byte loze ruimte na een 2-byte type om precies te zijn), omdat het het meest efficient (voor de CPU) is om alle variabelen op 4-bytes te alignen.
ik heb geen verstand van delphi, maar over het algemeen worden primitives aligned op hun eigen grootte... bytes hebben dus geen alignment, words op 2 bytes, dwords op 4 bytes etc. Als je TCompactDate 3 bytes zou zijn betekent dat dat het Year element mogelijk misaligned is als je er een array van maakt, en dus krijg je een padding van 1 byte.

Ik wed dat als je een structure maakt met 3 losse byte elementen erin dat ie dan wel gewoon 3 bytes is.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 27-05 15:56

Tomatoman

Fulltime prutser

.oisyn schreef op 19 maart 2004 @ 00:10:
[...]


ik heb geen verstand van delphi, maar over het algemeen worden primitives aligned op hun eigen grootte... bytes hebben dus geen alignment, words op 2 bytes, dwords op 4 bytes etc. Als je TCompactDate 3 bytes zou zijn betekent dat dat het Year element mogelijk misaligned is als je er een array van maakt, en dus krijg je een padding van 1 byte.

Ik wed dat als je een structure maakt met 3 losse byte elementen erin dat ie dan wel gewoon 3 bytes is.
Die weddenschap neem ik aan. De inzet: een kratje bier. :)

In de Delphi-versies 2 t/m 6 worden recordstructuren standaard uitgelijnd op een 4-byte grens. In Delphi 1 was dat op een 2-byte grens en in Delphi 7 is het een 8-byte grens geworden. Je kunt in Delphi 7 de byte alignment aanpassen met de {$ALIGN x} of {$Ax} switch, waarbij x het aantal bytes is.
When a record type is declared in the {$A+} state (the default), and when the declaration does not include a packed modifier, the type is an unpacked record type, and the fields of the record are aligned for efficient access by the CPU. The alignment is controlled by the type of each field. Every data type has an inherent alignment, which is automatically computed by the compiler. The alignment can be 1, 2, 4, or 8, and represents the byte boundary that a value of the type must be stored on to provide the most efficient access. The table below lists the alignments for all data types.
Zal ik je even het adres geven waar je het bier mag afleveren? :)

Een goede grap mag vrienden kosten.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
_Thanatos_ schreef op 18 maart 2004 @ 23:19:
/edit
ohja, daar ging dit topic niet echt over he... het ging om 3 bytes te alloceren, en dat kan met een array dus :)
En als je die 3 bytes dan echt efficient wilt inzetten, dan kun je Year zelfs tot 45099 laten lopen. ;->

(Of verder als je het aantal dagen sinds 01-01-0000 opslaat en dus geen gaten tussen maanden overhoudt.)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 27-05 15:56

Tomatoman

Fulltime prutser

_Thanatos_ schreef op 18 maart 2004 @ 21:44:
Ik wilde mijn datumvelden in een class wat compacter maken, omdat er een behoorlijke hoeveelheid instanties van die class kunnen onstaan (zit data in t.b.v. een treeview). Ik gebruik op dit moment TDateTime. Die is 64 bits en dat is natuurlijk veel meer dan noodzakelijk. Om de een of andere reden is TDate ook 64 bits, dus daar ben ik ook niet mee geholpen.
Tenzij je een paar honderd megabyte aan geheugen gaat alloceren, is een unpacked record type veel efficiënter. Bij een packed record is het eerste wat de CPU doet, de recordstructuur zodanig heralloceren dat hij alsnog netjes aligned is. Daarna voert hij zijn recordbewerkingen uit en ten slotte alignt hij het zaakje weer als een packed record. Doe maar eens wat snelheidstestjes, je zult zien dat een unpacked record meestal sneller is.

Een goede grap mag vrienden kosten.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

tomatoman schreef op 19 maart 2004 @ 00:33:
[...]

Die weddenschap neem ik aan. De inzet: een kratje bier. :)

In de Delphi-versies 2 t/m 6 worden recordstructuren standaard uitgelijnd op een 4-byte grens. In Delphi 1 was dat op een 2-byte grens en in Delphi 7 is het een 8-byte grens geworden. Je kunt in Delphi 7 de byte alignment aanpassen met de {$ALIGN x} of {$Ax} switch, waarbij x het aantal bytes is.

[...]

Zal ik je even het adres geven waar je het bier mag afleveren? :)
sorry, maar ik zie daar nog geen bewijs :? In VC++ is de standaard alignment ook 8, maar dat wil niet zeggen dat elk element op 8 bytes wordt gealigned: alleen elementen groter dan 8 bytes worden op slechts 8 bytes gealigned
Ik wil eigenlijk wel een stukje code zien met resultaat :)
and the fields of the record are aligned for efficient access by the CPU. The alignment is controlled by the type of each field

[ Voor 10% gewijzigd door .oisyn op 19-03-2004 01:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 27-05 15:56

Tomatoman

Fulltime prutser

Delphi:
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
type
  TGroot = record
    EenByte: Byte;
    TweeBytes: Word;
    VierBytes: Longword;
  end;

  TKlein = packed record
    EenByte: Byte;
    TweeBytes: Word;
    VierBytes: Longword;
  end;

  TOokGroot = record
    EenByte: Byte;
    NogEenByte: Byte;
    VierBytes: Longword;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  { recordgroottes tonen }
  ShowMessage(IntToStr(SizeOf(TGroot)));     // 8
  ShowMessage(IntToStr(SizeOf(TKlein)));     // 7
  ShowMessage(IntToStr(SizeOf(TOokGroot)));  // 8
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Groot: TGroot;
  Klein: TKlein;
  OokGroot: TOokGroot;
begin
  { adressen van de individuele recordelementen tonen }
  ShowMessage(Format('%p', [@Groot.EenByte]));       // 0012F644
  ShowMessage(Format('%p', [@Groot.TweeBytes]));     // 0012F646
  ShowMessage(Format('%p', [@Groot.VierBytes]));     // 0012F648

  ShowMessage(Format('%p', [@Klein.EenByte]));       // 0012F63D
  ShowMessage(Format('%p', [@Klein.TweeBytes]));     // 0012F63E
  ShowMessage(Format('%p', [@Klein.VierBytes]));     // 0012F640

  ShowMessage(Format('%p', [@OokGroot.EenByte]));    // 0012F634
  ShowMessage(Format('%p', [@OokGroot.NogEenByte])); // 0012F635
  ShowMessage(Format('%p', [@OokGroot.VierBytes]));  // 0012F638
end;
Tot dusver heb je gelijk. Maar nu waar het werkelijk om gaat.
.oisyn schreef op 19 maart 2004 @ 00:10:
[...]
Ik wed dat als je een structure maakt met 3 losse byte elementen erin dat ie dan wel gewoon 3 bytes is.
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type
  TDrieBytes = record
    EersteByte: Byte;
    TweedeByte: Byte;
    DerdeByte: Byte;
  end;

procedure TForm1.Button3Click(Sender: TObject);
var
  DrieBytes: TDrieBytes;
begin
  { recordgrootte tonen }
  ShowMessage(IntToStr(SizeOf(TDrieBytes)));          // 3

  { adressen van de individuele recordelementen tonen }
  ShowMessage(Format('%p', [@DrieBytes.EersteByte])); // 0012F649
  ShowMessage(Format('%p', [@DrieBytes.TweedeByte])); // 0012F64A
  ShowMessage(Format('%p', [@DrieBytes.DerdeByte]));  // 0012F64B
end;
Damn, je hebt gelijk :X. Dat gaat me een kratje kosten. Plak je zelf de postzegels als ik het opstuur? :)

Een goede grap mag vrienden kosten.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

"Stuur maar onder rembours", zei de Delphi leek tegen de guru :P

.edit: hmmm, TKlein geeft sizeof 7, dat strookt niet met de topicstart, die 4 bytes is terwijl hij eigenlijk een byte en een word gebruikt :?

.edit2: argh, ik las de topicstart verkeerd, never mind 8)7
Hoewel ik het idee heb dat iedereen de topicstart verkeerd begreep? Ik ging er aanvankelijk vanuit dat Day en Month op dezelfde byte terecht kwamen door optimalisatie. Maar dat kan natuurlijk niet, omdat die al 31*12 > 256 mogelijkheden beslaan. Day en Month krijgen dus ieder 1 byte, en Year krijgt er 2.

De vraag van de TS was waarom een type als 0..200000 4 bytes is ipv 2. Dat is natuurlijk simpelweg omdat er geen type bestaat van slechts 3 bytes long: je hebt een word en een dword, maar geen one-and-a-half-word oid :)

Alignment heeft er dus in z'n geheel niets mee te maken :)

[ Voor 123% gewijzigd door .oisyn op 19-03-2004 02:32 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 27-05 15:56

Tomatoman

Fulltime prutser

offtopic:
.oisyn schreef op 19 maart 2004 @ 02:21:
"Stuur maar onder rembours", zei de Delphi leek tegen de guru :P
_________

Prima, bij rembours betaalt de ontvanger. Wil je er nog een paar gratis bakstenen bij? :P

Een goede grap mag vrienden kosten.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

offtopic:
Alleen de verzendkosten natuurlijk, het krat bier betaal je zelf ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik ging er aanvankelijk vanuit dat Day en Month op dezelfde byte terecht kwamen door optimalisatie. Maar dat kan natuurlijk niet, omdat die al 31*12 > 256 mogelijkheden beslaan. Day en Month krijgen dus ieder 1 byte, en Year krijgt er 2.
Nee, ik hoopte op een nog betere optimalisatie... Day pas preies in 5 bits, Month in 4 bits en Year in 15 bits. Dat maakt samen 24 bits :)

日本!🎌


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 27-05 15:32
_Thanatos_ schreef op 19 maart 2004 @ 10:09:
[...]

Nee, ik hoopte op een nog betere optimalisatie... Day pas preies in 5 bits, Month in 4 bits en Year in 15 bits. Dat maakt samen 24 bits :)
Ik weet niet wat de tijdspanne is die je moet opslaan, maar je kan nog overwegen om naar 16-bits te gaan. In dat geval heb je een tijdsbestek van ca. 179 jaar beschikbaar. En dan kan je gewoon dagen tellen sinds 1-1-xxxx. Deze omzetting kan je dan standaard door Delphi uit laten voeren, door het gedeelte voor de komma te pakken van een TDateTime en daar een vaste offset voor te gebruiken.

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
179 jaar is op zich genoeg, maar het oogt niet zo professioneel als je niet verder dan bijvoorbeeld 1970-2149 kan selecteren... Want mensen gaan dat natúúrlijk uitproberen ;)

日本!🎌


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op 19 maart 2004 @ 02:36:
offtopic:
Alleen de verzendkosten natuurlijk, het krat bier betaal je zelf ;)
Is rembours niet net zo duur als het kratje zelf?

Verwijderd

OlafvdSpek schreef op 19 maart 2004 @ 00:38:
(Of verder als je het aantal dagen sinds 01-01-0000 opslaat en dus geen gaten tussen maanden overhoudt.)
Ahum, 01-01-0000 bestaat niet. 01-01-0001 daarentegen wel, probleem is alleen dat je dan ook rekening moet gaan houden met kalender correcties (zo telt september 1752 slechts 19 dagen).
Aangezien de TS gebruik maakt van een TreeView en dus voor iedere node een pointer (4 bytes) tot zijn beschikking heeft kan hij deze beter voor zijn opslag (mis)/gebruiken i.p.v. naar een 3-byte record te laten verwijzen. Delphi zelf slaat de datums als Float op maar aangezien de tijd niet van toepassing is en alleen de datum nodig is kun je 32 bits (achter de komma) schrappen en hou je een 32 bits integer over waar de datum precies in past. Deze 32 bits integer past perfect in je Data pointer.
Heb het evenin C++Builder 6 geprobeerd en werkt perfect:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int date = (int)MonthCalendar1->Date.Val;
  TreeView1->Items->Add(NULL, "Blaat")->Data = (void*)date;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TreeView1Click(TObject *Sender)
{
  if(TreeView1->Selected) {
    MonthCalendar1->Date = (int)TreeView1->Selected->Data;
  }
}
//---------------------------------------------------------------------------

[ Voor 24% gewijzigd door Verwijderd op 19-03-2004 11:40 ]


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
iedere node heeft een (pointer naar) een object met nog veel meer dan 1 datumpje :)

Bovendien is het raadzaam om de data niet *in* de treeview op te slaan, zo kun je dezelfde data makkelijker ergens anders hergebruiken... (ik gebruik dan ook een VirtualTree van DelphiGems).

日本!🎌


Verwijderd

_Thanatos_ schreef op 19 maart 2004 @ 12:15:
iedere node heeft een (pointer naar) een object met nog veel meer dan 1 datumpje :)
Ok, maar dat wisten wij natuurlijk niet.
Bovendien is het raadzaam om de data niet *in* de treeview op te slaan, zo kun je dezelfde data makkelijker ergens anders hergebruiken... (ik gebruik dan ook een VirtualTree van DelphiGems).
Zal best, maar dan nog kun je gewoon een datum als een 32-bits integer opslaan. Hoewel dit niet de meest 'zuinige' oplossing is qua geheugen is deze wel het makkelijkst hanteerbaar. Daarbij heb je sowieso 32-bit uitgespaard.
Pagina: 1