简体   繁体   English

C#数学不准确?

[英]C# Math Not Accurate?

I have two variables: counter and frequency . 我有两个变量: counterfrequency I am using these two variables as such: 我正在使用这两个变量,如:

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

As you can see, the counter counts up, until the point it matches the frequency, and then it resets to 0. At the moment, frequency is set to 100 . 如您所见,计数器开始计数,直到与频率匹配为止,然后重置为0。此刻, frequency设置为100 So the counter should reach 99, and then reset to 0. 因此计数器应达到99,然后重置为0。

I am using this counter to rotate an image at a rate of 100 times a second: 我正在使用此计数器以每秒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);
}

The script will rotate the image around a 360 degree plane. 该脚本将围绕360度平面旋转图像。 Since frequency is set to 100, it will go the full 360 degrees, since 100 * 3.6 is 360. This works great if the frequency is set to 100. However, if I change the frequency, it may not go the full 360 degrees; 由于频率设置为100,所以将旋转360度,因为100 * 3.6为360。如果将频率设置为100,则效果很好。但是,如果更改频率,则可能不会旋转360度;如果频率设置为100,则无法旋转360度。 or it may even go more than 360 degrees. 甚至可能超过360度。

A simple fix to this would be to change the rotation math to the following: 一个简单的解决方法是将旋转数学更改为以下内容:

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

However, doing this in actuality produces an odd result. 但是,实际上这样做会产生奇怪的结果。 The image never reaches the full 360 degree turn; 图像永远不会达到完整的360度旋转; and instead only reaches 300 degrees, before it eventually resets to 0. What is wrong with my math here? 而是只达到300度,然后才最终重置为0。这里我的数学怎么了?

You may have rounding issues. 您可能有舍入问题。 Be aware that if you want floating point results you need to do floating point math. 请注意,如果要浮点结果,则需要进行浮点运算。 In your code, you're mixing int s and double s, which may result in (unexpected) integer divisions. 在您的代码中,您正在混合intdouble ,这可能会导致(意外的)整数除法。 For example 360 / frequency will not result in a floating point number, as both frequency and 360 are int s (for example 360 / 100 == 3!!). 例如360 / frequency将不会产生浮点数,因为频率和360均为int (例如360/100 == 3 !!)。

Try changing your code to use floating point operations consistently as follows: 尝试更改代码以一致地使用浮点运算,如下所示:

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);
}

And the last example you gave should read: 您给出的最后一个示例应为:

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

with counter and frequency being double s. counterfrequencydouble s。


EDIT: It would suffice to change the last line to 编辑:将最后一行更改为

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

and leave the variables as int . 并将变量保留为int Your last line in updateTimer doesn't work as 3.6 is hardcoded, but depending on frequency counter * 3.6 may not reach/be greater than 360°. 由于3.6是硬编码的,因此您在updateTimer中的最后一行不起作用,但是取决于频率counter * 3.6可能不会达到/大于360°。

Example: 例:

frequency = 50
counter = 49
counter * 3.6 = 176.4

frequency = 150
counter = 149
counter * 3.6 = 536.4

So you always need to calculate the degrees to rotate in every step according to frequency and not hardcode them as if frequency was 100. 因此,您始终需要根据frequency计算每一步的旋转角度,而不要像frequency为100那样对其进行硬编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM