I'm currently coding a little download manager and I get a funny output when I try to calculate the download-progress in percent. This is what i use to calculate it:
int progress = (byte_counter * 100) / size;
System.out.println("("+byte_counter+" * 100) = "+(byte_counter * 100)
+" / "+size+" = "+progress);
byte-counter
is an int (it counts the total bytes read from the InputStream
) and size
is the length of the downloaded file in bytes.
This works great with small downloads. But when i get to bigger files (40MB) it starts making funny things. The Output for the calculation looks like this:
[...]
(21473280 * 100) = 214732开发者_如何学Python8000 / 47659008 = 45
(21474720 * 100) = 2147472000 / 47659008 = 45
(21476160 * 100) = -2147351296 / 47659008 = -45
(21477600 * 100) = -2147207296 / 47659008 = -45
[...]
I don't know why, but the calculation gets negative. Since an normal Integer should be fine with numbers till 231-1, this shouldn't be the problems root. But what am I missing?
See http://en.wikipedia.org/wiki/Arithmetic_overflow
To fix in java, try using a long
instead.
int progress = (int) ((byte_counter * 100L) / size);
or reverse order of operations
int progress = (int) (((float) byte_counter) / size) * 100);
21476160 * 100 = 2 147 616 000
is greater than 2 147 483 647
, the max int.
You're overflowing.
Use long
for your calculations.
2^31-1 = 2147483647 < 21476160 * 100 = 2147616000
You should use a long -- 2147760000 in binary is 10000000 00000100 00110111 10000000 and since the most significant bit is 1 it is interpreted as a negative number.
精彩评论