右圆环

发布于 2024-10-13 04:11:34 字数 522 浏览 7 评论 0原文

我必须以步骤 0.5 从 0 循环到 5。但当值为 5 时,循环应该相反。

bool forward = true;
int counter = 0;
float val = 5.0f;

// And somewhere in global app cycle:
if (val <= 0.0 && forward) forward = false;
if (forward) val -= .5f;

if (val >= 5.0 && !forward) forward = true;
if (!forward) val += .5f;

但结果有时是负数,我认为,这是一个有点难看的代码。

0.2
0.18
0.16
0.14
0.12
0.1
0.08
0.06
0.04
0.02
2.98023e-08
-0.02
2.98023e-08
0.02
0.04
0.06
0.08
0.1
0.12
0.14
0.16
0.18
0.2
0.2
0.18

I have to cycle from 0 to 5 with step 0.5. But the cycle should be reversed when the value is 5.

bool forward = true;
int counter = 0;
float val = 5.0f;

// And somewhere in global app cycle:
if (val <= 0.0 && forward) forward = false;
if (forward) val -= .5f;

if (val >= 5.0 && !forward) forward = true;
if (!forward) val += .5f;

But the result is sometimes negative numbers and, I think, that's a bit ugly code.

0.2
0.18
0.16
0.14
0.12
0.1
0.08
0.06
0.04
0.02
2.98023e-08
-0.02
2.98023e-08
0.02
0.04
0.06
0.08
0.1
0.12
0.14
0.16
0.18
0.2
0.2
0.18

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

染柒℉ 2024-10-20 04:11:34

您遇到的问题是 0.2 无法精确地用浮点表示。因此,当您编写 val -= 0.2 时,您真正做的是 val -= 0.20000000298023224;。因此,您会积累错误。

解决方案是不使用浮点来控制循环。请改用 int,并乘以常量以获得 val。例如:

int inc = -1;
int i = 10;

while (whatever)
{
    if (i == 0) inc = +1;
    if (i == 10) inc = -1;

    i += inc;

    float val = i * 0.02;
}

The problem you are experiencing is that 0.2 cannot be exactly represented in floating-point. So when you write val -= 0.2, what you're really doing is val -= 0.20000000298023224;. Therefore, you accumulate errors.

The solution is to not use floating-point to control your loop. Use an int instead, and multiply by a constant to get val. e.g.:

int inc = -1;
int i = 10;

while (whatever)
{
    if (i == 0) inc = +1;
    if (i == 10) inc = -1;

    i += inc;

    float val = i * 0.02;
}
回梦 2024-10-20 04:11:34

在步骤 1 中使用从 0 到 10 的整数,或者在步骤 5 中使用从 0 到 50 的整数。浮点数可以是 0.00000012,因此它不小于或等于 0.0。
您可以在需要时根据循环变量计算浮点数。

Use integers for such cycles from 0 to 10 with step 1 or from 0 to 50 with step 5. Float may be 0.00000012 and so it is not less or equal than 0.0.
You can calculate the float from your cycle variable when needed.

与往事干杯 2024-10-20 04:11:34

|值 - 5.0| < eps && |值 - 0 | < eps 哪里 | |在您的情况下 fabsf() 我想

还请记住,每当减去两个几乎相等(浮点表示)的值时,精度就会有所损失。

|val - 5.0| < eps && |val - 0 | < eps where | | in your case fabsf() i guess

also keep in mind that there is some loss in precision whenever two almost equal (floating point representation) values are subtracted.

冷…雨湿花 2024-10-20 04:11:34

可以不指定每次移动的距离,而指定划分的数量吗?
这样,您的值就不会因精度/舍入误差而漂移
例如:

void Step(float from, float to, int divisions)
{
    float range = to - from;
    float perDivision = range / divisions;

    int i = 0;
    for(;;)
    {
        for(; i < divisions; ++i)
        {
           UseCurrentValue(from + (i * perDivision));
        }
        for(; i > 0; --i)
        {
           UseCurrentValue(from + (i * perDivision));
        }
    }
}

void UseCurrentValue(float val)
{
   // Do something with val here.
}

Instead of specifying the distance to move each time, could the number of divisions be specified?
This way, your value won't ever drift due to precision/rounding errors
EG:

void Step(float from, float to, int divisions)
{
    float range = to - from;
    float perDivision = range / divisions;

    int i = 0;
    for(;;)
    {
        for(; i < divisions; ++i)
        {
           UseCurrentValue(from + (i * perDivision));
        }
        for(; i > 0; --i)
        {
           UseCurrentValue(from + (i * perDivision));
        }
    }
}

void UseCurrentValue(float val)
{
   // Do something with val here.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文