C# 数学不准确

本文关键字:不准确 | 更新日期: 2023-09-27 18:29:57

我有两个变量:counterfrequency。我正在使用这两个变量:

counter = counter >= frequency ? 0 : counter + 1;

如您所见,计数器计数,直到它与频率匹配的点,然后重置为 0。目前,frequency设置为100 。所以计数器应该达到 99,然后重置为 0。

我正在使用此计数器以每秒 100 次的速度旋转图像:

private int counter = 0;
private int frequency = 100;
private DispatcherTimer dispatch = new DispatcherTimer();
public Timer()
{
    this.dispatch.Interval = TimeSpan.FromMilliseconds(1000 / frequency);
    this.dispatch.Tick += new EventHandler(updateTimer);
    this.dispatch.Start();
}
private void updateTimer(object sender, EventArgs e)
{
    counter = counter >= frequency ? 0 : counter + 1;
    saveImage.RenderTransform = new RotateTransform(counter * 3.6);
}

该脚本将围绕 360 度平面旋转图像。由于频率设置为 100,它将完全 360 度,因为 100 * 3.6 是 360。如果频率设置为 100,这非常有用。但是,如果我更改频率,它可能不会完全 360 度;或者它甚至可能超过 360 度。

对此的简单解决方法是将旋转数学更改为以下内容:

    saveImage.RenderTransform = new RotateTransform(counter * (360 / frequency));

然而,实际上这样做会产生一个奇怪的结果。图像永远不会达到完整的 360 度转弯;相反,在最终重置为 0 之前,它只达到 300 度。我的数学有什么问题?

C# 数学不准确

您可能遇到舍入问题。请注意,如果你想要浮点结果,你需要做浮点数学。在代码中,混合了 int s 和 double s,这可能会导致(意外的(整数除法。例如,360 / frequency不会产生浮点数,因为频率和360都是int秒(例如 360/100 == 3!!!

尝试更改代码以一致地使用浮点运算,如下所示:

private double counter = 0.0;
private double frequency = 100.0;
private DispatcherTimer dispatch = new DispatcherTimer();
public Timer()
{
    // You may want integer division in this line to get full milliseconds
    this.dispatch.Interval = TimeSpan.FromMilliseconds((int)(1000.0 / frequency));
    this.dispatch.Tick += new EventHandler(updateTimer);
    this.dispatch.Start();
}
private void updateTimer(object sender, EventArgs e)
{
    counter = counter >= frequency ? 0.0 : counter + 1.0;
    saveImage.RenderTransform = new RotateTransform(counter * 3.6);
}

你举的最后一个例子应该是:

saveImage.RenderTransform = new RotateTransform(counter * (360.0 / frequency));

随着counterfrequencydouble S。


编辑:将最后一行更改为

saveImage.RenderTransform = new RotateTransform(counter * (360.0 / frequency));

并将变量保留为 intupdateTimer的最后一行不起作用,因为3.6是硬编码的,但根据频率的不同,counter * 3.6可能无法达到/大于 360°。

例:

frequency = 50
counter = 49
counter * 3.6 = 176.4
frequency = 150
counter = 149
counter * 3.6 = 536.4

因此,您始终需要根据frequency计算每一步中旋转的度数,而不是像frequency是 100 一样对它们进行硬编码。