C# 百分比计算突然变为负数
C# percentage calculation suddenly goes negative
我有一个程序可以下载一些讲座视频以供离线观看。我使用下面的代码来下载和计算百分比。大约 32-33% 的计算百分比总是负数,但以一种奇怪的方式 (33 -> -33 -> -32 -> -31 -> -30 等...)直到它再次达到 33。至此下载完成。我什至手动计算。调试输出也在代码下方。
这种情况一直在发生,所以我肯定做错了什么,但是在哪里呢?
private async Task CopyStream(
Lecture lecture,
Stream source,
Stream destination,
int sourceLength,
CancellationToken token,
int bufferSize = (16 * 1024))
{
var buffer = new byte[bufferSize];
if (sourceLength <= 0) return;
var totalBytesCopied = 0;
var bytesRead = -1;
while (bytesRead != 0)
{
bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, token);
if (bytesRead == 0) break;
await destination.WriteAsync(buffer, 0, buffer.Length, token);
totalBytesCopied += bytesRead;
var progress = (int)Math.Round((double)(100 * totalBytesCopied) / sourceLength);
Debug.WriteLine(
$"Lecture={lecture.Title}, " +
$"sourceLength={sourceLength}, " +
$"totalBytesCopied={totalBytesCopied}, " +
$"bytesRead={bytesRead}, progress={progress}");
RaiseLectureDownloadProgressChangedEvent(null,
new LectureDownloadProgressChangedEventArgs(lecture, progress));
}
}
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21404088, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21420472, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21436856, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21453240, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21469624, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21486008, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21502392, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21518776, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21535160, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21551544, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21567928, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21584312, bytesRead=16384, progress=-32
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21600696, bytesRead=16384, progress=-32
Lasse V. Karlsen 在评论中给出了正确的解释。
要修复它,请更改:
var progress = (int) Math.Round((double) (100 * totalBytesCopied) / sourceLength);
进入:
var progress = (int) Math.Round(((double)100) * totalBytesCopied / sourceLength);
或者简单地说:
var progress = (int) Math.Round(100.0 * totalBytesCopied / sourceLength);
正如他所说,这将迫使一切都以浮点形式完成。在这种情况下,整数将自动(隐式)转换为 double
。我删除了一个多余的括号(但你也可以保留它)。
我有一个程序可以下载一些讲座视频以供离线观看。我使用下面的代码来下载和计算百分比。大约 32-33% 的计算百分比总是负数,但以一种奇怪的方式 (33 -> -33 -> -32 -> -31 -> -30 等...)直到它再次达到 33。至此下载完成。我什至手动计算。调试输出也在代码下方。
这种情况一直在发生,所以我肯定做错了什么,但是在哪里呢?
private async Task CopyStream(
Lecture lecture,
Stream source,
Stream destination,
int sourceLength,
CancellationToken token,
int bufferSize = (16 * 1024))
{
var buffer = new byte[bufferSize];
if (sourceLength <= 0) return;
var totalBytesCopied = 0;
var bytesRead = -1;
while (bytesRead != 0)
{
bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, token);
if (bytesRead == 0) break;
await destination.WriteAsync(buffer, 0, buffer.Length, token);
totalBytesCopied += bytesRead;
var progress = (int)Math.Round((double)(100 * totalBytesCopied) / sourceLength);
Debug.WriteLine(
$"Lecture={lecture.Title}, " +
$"sourceLength={sourceLength}, " +
$"totalBytesCopied={totalBytesCopied}, " +
$"bytesRead={bytesRead}, progress={progress}");
RaiseLectureDownloadProgressChangedEvent(null,
new LectureDownloadProgressChangedEventArgs(lecture, progress));
}
}
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21404088, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21420472, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21436856, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21453240, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21469624, bytesRead=16384, progress=33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21486008, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21502392, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21518776, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21535160, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21551544, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21567928, bytesRead=16384, progress=-33
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21584312, bytesRead=16384, progress=-32
Lecture=Lecture1, sourceLength=65777753, totalBytesCopied=21600696, bytesRead=16384, progress=-32
Lasse V. Karlsen 在评论中给出了正确的解释。
要修复它,请更改:
var progress = (int) Math.Round((double) (100 * totalBytesCopied) / sourceLength);
进入:
var progress = (int) Math.Round(((double)100) * totalBytesCopied / sourceLength);
或者简单地说:
var progress = (int) Math.Round(100.0 * totalBytesCopied / sourceLength);
正如他所说,这将迫使一切都以浮点形式完成。在这种情况下,整数将自动(隐式)转换为 double
。我删除了一个多余的括号(但你也可以保留它)。