2

我目前正在编写一个小下载管理器,当我尝试以百分比计算下载进度时,我得到了一个有趣的输出。这是我用来计算它的:

int progress = (byte_counter * 100) / size;
System.out.println("("+byte_counter+" * 100) = "+(byte_counter * 100)
  +" / "+size+" = "+progress);

byte-counter是一个 int (它计算从 读取的总字节数InputStream)并且size是下载文件的长度(以字节为单位)。

这适用于小型下载。但是当我获得更大的文件(40MB)时,它开始制作有趣的东西。计算的输出如下所示:

[...]
(21473280 * 100) = 2147328000 / 47659008 = 45
(21474720 * 100) = 2147472000 / 47659008 = 45
(21476160 * 100) = -2147351296 / 47659008 = -45
(21477600 * 100) = -2147207296 / 47659008 = -45
[...]

我不知道为什么,但计算结果为负。由于正常的整数应该可以处理 2 31 -1 之前的数字,因此这不应该是问题的根源。但我错过了什么?

4

4 回答 4

7

http://en.wikipedia.org/wiki/Arithmetic_overflow

要在 java 中修复,请尝试使用 along代替。

int progress = (int) ((byte_counter * 100L) / size);

或相反的操作顺序

int progress = (int) (((float) byte_counter) / size) * 100);
于 2011-05-18T20:49:59.177 回答
5

21476160 * 100 = 2 147 616 000大于2 147 483 647,最大整数。

你溢出来了。

用于long您的计算。

于 2011-05-18T20:51:11.563 回答
3
2^31-1 = 2147483647  < 21476160 * 100 = 2147616000
于 2011-05-18T20:51:43.537 回答
2

您应该使用 long -- 2147760000 在二进制中是 10000000 00000100 00110111 10000000 并且由于最高有效位是 1 它被解释为负数。

于 2011-05-18T20:53:44.253 回答