Amadeus Hein
Amadeus Hein

Reputation: 716

Why can't I use int to calculate bytes to gigabytes?

I ran into some trouble when converting bytes to gigabytes in my current project. Initially I did this:

 long requiredDiskSpace = 5000000000000; // In bytes
 int gb = (int)requiredDiskSpace / 1024 / 1024 / 1024;

This calculation becomes 0. (Correct should be 4 656). Then I switched to the decimal type, like this:

 long requiredDiskSpace = 5000000000000; // In bytes
 decimal gb = requiredDiskSpace / 1024 / 1024 / 1024;
 int gbAsInt = (int)gb;

This calculation (correctly) makes gbAsInt 4 656.

Now, my question is simply; why? To me, the calculations look similar, as I'm not interested in any decimal numbers I don't understand why I can't just use int in the actual calculation.

Upvotes: 3

Views: 1090

Answers (7)

Filip Ekberg
Filip Ekberg

Reputation: 36287

The problem is (int)requiredDiskSpace, the value 5000000000000 is way too big for an integer.

Upvotes: 8

SynerCoder
SynerCoder

Reputation: 12766

You are trying to cast 5000000000000 to an integer. This will not work properly because that number is greater than Int.MaxValue So you should infact do:

int gb = (int)(requiredDiskSpace / 1024 / 1024 / 1024);

Upvotes: 9

Gene
Gene

Reputation: 4232

You are casting the byte value to an int, which is not able to hold such a big number.

long test = 5000000000000;
int value = (int)test; // value = 658067456

Dividing this value three times by 1024 will result in 627 / 1024 which equals (in integer arithmetic) 0.

Upvotes: 2

Joey
Joey

Reputation: 354416

Your problem is (int) there. You are casting your long to int that way. But 5000000000000 cannot fit in a 32-bit integer so you end up with a completely different number between −231 and 231. Dividing that by 1073741824 then yields 0.

I suspect you just wanted the result to be casted to int:

int gb = (int)(requiredDiskSpace / 1024 / 1024 / 1024);

Upvotes: 5

Krešimir Lukin
Krešimir Lukin

Reputation: 399

Cast after calculation:

    long requiredDiskSpace = 5000000000000; // In bytes
    int gb = (int)(requiredDiskSpace / 1024 / 1024 / 1024);

When you cast immediately to int you lose value.

Upvotes: 3

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174299

The reason is your cast. If you use parenthesis, it will work correctly:

(int)(requiredDiskSpace / 1024 / 1024 / 1024)

What happens in your code is this:

  1. 5000000000000 is cast to an int, resulting in 658067456 because of integer overflow.
  2. 658067456 is divided by 1024 resulting in 642644
  3. 642644 is divided by 1024 resulting in 627.58203125. As all operations are taking place on ints, the result really is 627 as decimals are stripped away.
  4. 627 is divided by 1024 resulting in 0.6123.. Again, decimals are stripped away and you end up with 0

Upvotes: 4

Marco
Marco

Reputation: 57573

Because when you use integer division, result is truncated to be an integer everytime.
So you have zero in first attempt, even because 5000000000000 is too big to be stored in an int var.
You should use

double gb = 1.0d * requiredDiskSpace / (1024 * 1024 * 1024);

Upvotes: 1

Related Questions