Like said in the comments, your problem is that you are overflowing your 32-bit integer with a 64-bit value, thus it gets truncated to 32 bit (the top 32 bits are simply thrown away, so f.ex. a value of 5 Gb will be understood as 1 Gb). Also, since you are talking about sizes, you really shouldn't use integers, as you will then throw away half of your range on values that can't be valid in any case (a file, f.ex., can't have a size of -2048 bytes).
I have for some time used the following two functions. The one without a Decimals parameter will return up to 3 decimals, but only if necessary (ie. if the size is exactly 1 Gb, then it will return the string "1 Gb" and not "1,000 Gb" (if your decimal point is the comma)).
The one with a Decimals parameter will always return the value with that number of decimals.
Also note, that the calculation is done using the binary scale (1 Kb = 1024 bytes). If you want it changed to the decimal scale, you should change the 1024 values with 1000 and probably the SizeUnits array as well.
CONST
SizeUnits : ARRAY[0..8] OF PChar = ('bytes','Kb','Mb','Gb','Tb','Pb','Eb','Zb','Yb');
FUNCTION SizeStr(Size : UInt64) : String; OVERLOAD;
VAR
P : Integer;
BEGIN
Result:=SizeStr(Size,3);
IF Size>=1024 THEN BEGIN
P:=PRED(LastDelimiter(' ',Result));
WHILE COPY(Result,P,1)='0' DO BEGIN
DELETE(Result,P,1);
DEC(P)
END;
IF CharInSet(Result[P],['.',',']) THEN DELETE(Result,P,1)
END
END;
FUNCTION SizeStr(Size : UInt64 ; Decimals : BYTE) : String; OVERLOAD;
VAR
I : Cardinal;
S : Extended;
BEGIN
S:=Size;
FOR I:=LOW(SizeUnits) TO HIGH(SizeUnits) DO BEGIN
IF S<1024.0 THEN BEGIN
IF I=LOW(SizeUnits) THEN Decimals:=0;
Result:=Format('%.'+IntToStr(Decimals)+'f',[S]);
Result:=Result+' '+StrPas(SizeUnits[I]);
EXIT
END;
S:=S/1024.0
END
END;
If you are using a compiler version of Delphi that doesn't have the UInt64 type, you can use Int64 instead (you probably won't come acros files larger than 8 Eb = apprx. 8.000.000 TeraBytes in your lifetime :-), so Int64 should be sufficient in this case).
Also, the CharInSet function is one from the Unicode versions of Delphi. It can be implemneted as:
TYPE TCharacterSet = SET OF CHAR;
FUNCTION CharInSet(C : CHAR ; CONST Z : TCharacterSet) : BOOLEAN; INLINE;
BEGIN
Result:=(C IN Z)
END;
or replaced directly in the source, if you are using a pre-Unicode version of Delphi.
bytes
makes that very clear! It shows as 1767128484, not 323889675684 – ParteeStrFormatByteSizeEx
function for this kind of stuff. – Flite