-3

What is the correct way to convert size in bytes to KB, MB, GB in Delphi.

Arch Brooks
  • 183
  • 1
  • 3
  • 19
  • 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
  • 2
    Do 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 Answers2

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