C# 数学不准确
本文关键字:不准确 | 更新日期: 2023-09-27 18:29:57
我有两个变量:counter
和frequency
。我正在使用这两个变量:
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 度。我的数学有什么问题?
您可能遇到舍入问题。请注意,如果你想要浮点结果,你需要做浮点数学。在代码中,混合了 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));
随着counter
和frequency
被double
S。
编辑:将最后一行更改为
saveImage.RenderTransform = new RotateTransform(counter * (360.0 / frequency));
并将变量保留为 int
。updateTimer
的最后一行不起作用,因为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 一样对它们进行硬编码。