What is the correct way to convert size in bytes to KB, MB, GB in Delphi.
Asked
Active
Viewed 8,747 times
-3
-
Since you didn't specify what you mean by *correct way* (because if you're looking for a correct way, you must have some incorrect, which you didn't show us), so I'm taking [this question](http://stackoverflow.com/q/1285979/960757) as related. – TLama May 30 '15 at 17:25
-
2Do you mean KB, MB, and GB as is commonly used for RAM (1024 B = 1 KB), or do you mean how it is used for storage (1000 B = 1 KB)? – Ron Maupin May 30 '15 at 18:01
-
[Incorrect Result of Total Download's Code](http://stackoverflow.com/questions/30418940/incorrect-result-of-total-downloads-code/30419069?noredirect=1#comment49007757_30419069) - Here is complete code to convert B and GB and so on. For some other reasons: 1 KiloMeter = 1000 Meters, 1 KiloByte = 1024 Bytes. 1 KiloMeters = 10^3 meters, 1 KiloByte = 2^10 bytes. And next: n-meters=10^(3*n), n-bytes = 2^(10*n) bytes. – Abelisto May 30 '15 at 19:06
2 Answers
12
I suppose you want a Delphi solution. Try this
uses
Math;
function ConvertBytes(Bytes: Int64): string;
const
Description: Array [0 .. 8] of string = ('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
var
i: Integer;
begin
i := 0;
while Bytes > Power(1024, i + 1) do
Inc(i);
Result := FormatFloat('###0.##', Bytes / IntPower(1024, i)) + ' ' + Description[i];
end;

Jens Borrisholt
- 6,174
- 1
- 33
- 67
7
Like this:
KB := Bytes / 1024;
MB := Bytes / (1024*1024);
GB := Bytes / (1024*1024*1024);
This produces floating point values. If you desire integer values then round these values:
KB := Round(Bytes / 1024);
MB := Round(Bytes / (1024*1024));
GB := Round(Bytes / (1024*1024*1024));
Or truncate using integer division:
KB := Bytes div 1024;
MB := Bytes div (1024*1024);
GB := Bytes div (1024*1024*1024);
Of course, I don't know what you mean by "correct". If you are looking for a function that converts an integer number of bytes to a human readable string you could use something along these lines:
const
OneKB = 1024;
OneMB = OneKB * OneKB;
OneGB = OneKB * OneMB;
OneTB = Int64(OneKB) * OneGB;
type
TByteStringFormat = (bsfDefault, bsfBytes, bsfKB, bsfMB, bsfGB, bsfTB);
function FormatByteString(Bytes: UInt64; Format: TByteStringFormat = bsfDefault): string;
begin
if Format = bsfDefault then begin
if Bytes < OneKB then begin
Format := bsfBytes;
end
else if Bytes < OneMB then begin
Format := bsfKB;
end
else if Bytes < OneGB then begin
Format := bsfMB;
end
else if Bytes < OneTB then begin
Format := bsfGB;
end
else begin
Format := bsfTB;
end;
end;
case Format of
bsfBytes:
Result := SysUtils.Format('%d bytes', [Bytes]);
bsfKB:
Result := SysUtils.Format('%.1n KB', [Bytes / OneKB]);
bsfMB:
Result := SysUtils.Format('%.1n MB', [Bytes / OneMB]);
bsfGB:
Result := SysUtils.Format('%.1n GB', [Bytes / OneGB]);
bsfTB:
Result := SysUtils.Format('%.1n TB', [Bytes / OneTB]);
end;
end;

David Heffernan
- 601,492
- 42
- 1,072
- 1,490
-
There is no control for these statements. You probably need a "if" or "case" statement to do this properly. – Arch Brooks May 30 '15 at 17:18
-
@ArchBrooks I think a big part of your problem here is that you have not decided what the spec is – David Heffernan May 30 '15 at 18:07
-
I'm getting `E2099 Overflow in conversion or arithmetic operation` on the constant `OneTB = OneKB * OneGB;`. No biggie for my purposes though, I won't need this for files larger than even `1 MB`. – Jerry Dodge Jul 29 '18 at 15:23
-
1@Jerry Thanks. Needs a cast to perform 64 bit arithmetic, see update – David Heffernan Jul 29 '18 at 15:31