[delphi] vreemd gedrag case bij int64

Pagina: 1
Acties:

  • Mayco
  • Registratie: Augustus 2002
  • Laatst online: 24-05 17:37
ik heb dit stuk code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
function goodsize(size: int64): string;
begin

  case size of
    0..1024-1:                       Result := FormatFloat('0.##', size) + ' bytes';
    1024..(1024*1024)-1:             Result := FormatFloat('0.##', size / 1024) + ' kB';
    (1024*1024)..(1024*1024*1024)-1: Result := FormatFloat('0.##', size / (1024*1024)) + ' MB';
  else
                                     Result := FormatFloat('0.##', size / (1024*1024*1024)) + ' GB';
  end;

end;


nu, als ik
code:
1
str := goodsize(20941529008);

doe, krijg ik mooi een getal met GB achter (19.5 gb) (neemt else)

maar als ik dit doe:
code:
1
str := goodsize(size := 26222157824);

dan neemt hij de derde, en krijg ik iets met een MB (25007.4 mb) achter.

het ligt niet aan de FormatFloat, want als ik debug kan ik het mooi zien springen naar de 3e bij 26... en naar else bij 20...

wie weet wat hier gaande is?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

int64 is geen standaard type op een 32 bits processor en moet dus geemuleerd worden. Aangezien het 64 bits breed is past het niet in een register en dat is net wat het case statement gebruikt. De compiler waarschuwd je nergens voor, maar vertaald m naar een 32 bits getal (Integer). De oplossing is een ouderwetse if gebruiken.
Delphi:
1
2
3
4
5
6
7
8
9
10
11
function goodsize(size: int64): string;
begin
  if size < 1024 then
    Result := FormatFloat('0.##', size) + ' bytes'
  else if size < (1024*1024) then
    Result := FormatFloat('0.##', size / 1024) + ' kB'
  else if size < (1024*1024*1024) then
    Result := FormatFloat('0.##', size / (1024*1024)) + ' MB'
  else
    Result := FormatFloat('0.##', size / (1024*1024*1024)) + ' GB';
end;


PS: Hetzelfde geldt trouwens voor een for loop. De oplossing daar is een while loop gebruiken natuurlijk :)

We adore chaos because we like to restore order - M.C. Escher


  • Mayco
  • Registratie: Augustus 2002
  • Laatst online: 24-05 17:37
bedankt! zo werkt het wel. vind het wel maar dom dat de compiler zelfs geen hint geeft dat er iets fout kan gaan, als je dit niet weet moet je maar raden waarom die int64 niet werkt.

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

_Thanatos_

Ja, en kaal

De compiler begint gewoon pas te jammeren als je een 64-bits integer als case-label gebruikt, om bijvoorbeeld ook TB's te ondersteunen... dus wat dat betreft zit het allemaal nog wel goed ;)

日本!🎌


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

Tomatoman

Fulltime prutser

LordLarry schreef op 06 maart 2004 @ 00:22:
int64 is geen standaard type op een 32 bits processor en moet dus geemuleerd worden. Aangezien het 64 bits breed is past het niet in een register en dat is net wat het case statement gebruikt.
Dat is helaas de manier waarop Delphi het aanpakt - iedere Int64 wordt op de stack gezet. Dat heeft als neveneffect dat code die intensief gebruik maakt van Int64 niet erg efficiënt is. Diverse C-compilers gebruiken twee registers om één 64-bits integer op te slaan, wat veel efficiënter is. Het kan dus wel degelijk.

Een goede grap mag vrienden kosten.