-1

I have created a header data retriever where the user enters the URL and it returns size in mb
My code works fine but it does not shows the floating value

if (long.TryParse(resp.Headers.Get("Content-Length"), out ContentLength))
{
    string File_Size;

    if (ContentLength >= 1073741824)
    {
        result = ContentLength / 1073741824;

        kbmbgb.Text = "GB";
    }
    else if (ContentLength >= 1048576)
    {
        result = ContentLength / 1048576;

        kbmbgb.Text = "MB";
    }
    else if (ContentLength >= 1024)
    {
        result = ContentLength / 1024;

        kbmbgb.Text = "KB";
    }
    else
    {
        result = ContentLength;
        kbmbgb.Text = "BYTE";

    }

    File_Size = result.ToString("0.00");
    sizevaluelabel.Text = File_Size;
}
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Ankit Singh
  • 173
  • 2
  • 19
  • Probably the same as KB but divide by 1024 again. https://www.gbmb.org/megabytes – Daniel Gale Mar 28 '18 at 17:58
  • https://stackoverflow.com/questions/37774694/dividing-two-numbers – Chris Mar 28 '18 at 18:00
  • long is a long integer, and dividing two integers in C# gives you an integer. – Tim Mar 28 '18 at 18:03
  • Even if I convert to float i can't work – Ankit Singh Mar 28 '18 at 18:04
  • Your code can be much shorter... **`long size = 1024 * 1024 * 892 + 256 * 1000; var XB = new[] { " Bytes", " KB", " MB", " GB", " TB", " PB" }; var inx = (int)Math.Log(size, 1024); var text = (size / Math.Pow(1024, inx)).ToString("#.00") + XB[inx];`** – Eser Mar 28 '18 at 18:18
  • Use result = ContentLength / 1048576.0; and ensure you declared result as a double. – Hans Passant Mar 28 '18 at 18:30

2 Answers2

3

The problem is you are working entirely in integral types that don't provide any space for decimal storage. You need to convert to a double or decimal. If you're using C# 7 (supports Tuples) you can do this:

public (double, string) AdjustFileSize(long fileSizeInBytes)
{
    var names = {"BYTES", "KB", "MB", "GB"};

    double sizeResult = fileSizeInBytes * 1.0;
    int nameIndex = 0;
    while (sizeResult > 1024 && nameIndex < names.Length)
    {
        sizeResult /= 1024; 
        nameIndex++;
    }

    return (sizeResult, names[nameIndex]);
}

Here's another fun way:

public (double, string) AdjustFileSize(long fileSizeInBytes)
{
    if (fileSizeInBytes <= 0) return (0.0, "BYTES");

    var names = {"BYTES", "KB", "MB", "GB"};
    var sizes = {1.0, 1024.0, 1048576.0, 1073741824.0};

    var index = Math.Log(fileSizeInBytes, 1024);
    return (fileSizeInBytes / sizes[index], names[index]);
}

Then call either version like this:

long ContentLength = 0;
if (long.TryParse(resp.Headers.Get("Content-Length"), out ContentLength))
{
    var size = AdjustFileSize(ContentLength);
    sizevaluelabel.Text = size.Item1.ToString("0.00");
    kbmbgb.Text = size.Item2;
}

If you can't use Tuples, I'd define a small class to communicate the same info, or maybe even a struct given the small size.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
0

Most of the above answer was too hard to understand to the beginners so after few trying and trying i found my own way. here is the answer.

                double ContentLength = 0;
                double result;
                if (double.TryParse(resp.Headers.Get("Content-Length"), out ContentLength))
                {
                    string File_Size;

                    if (ContentLength >= 1073741824.00)
                    {
                        result = ContentLength / 1073741824.00;
                        kbmbgb.Text = "GB";
                    }
                    else if (ContentLength >= 1048576.00)
                    {
                        result = ContentLength / 1048576.00;
                        kbmbgb.Text = "MB";
                    }
                    else if (ContentLength >= 1024.00)
                    {
                        result = ContentLength / 1024.00;
                        kbmbgb.Text = "KB";
                    }
                    else
                    {
                        result = ContentLength;
                        kbmbgb.Text = "BYTE";

                    }
                    File_Size = result.ToString("0.00");
                    sizevaluelabel.Text = File_Size;
Ankit Singh
  • 173
  • 2
  • 19
  • just change long to double – Ankit Singh Mar 28 '18 at 19:07
  • What was for ex too hard to understand in *"Most of the above answer"*? – Eser Mar 28 '18 at 20:06
  • coding doesn't need to be complex it can be easy and anyways most of them tried to use to hard methods and none of them looked for the flaw in the code – Ankit Singh Mar 28 '18 at 20:13
  • See **Hans Passant's** comment. what is hard to understand? what is hard to implement? All you need to do is adding a `.0` to your constants (BTW your second 0s in doubles `xxx.00` is unnecessary). What is hard with **Chris's** comment? that link explains the integer division problem. **Tim** also said the same this – Eser Mar 28 '18 at 20:22