【问题标题】:C (C++, Objective-C) typecast from float to int results in decremented int从 float 到 int 的 C (C++, Objective-C) 类型转换导致 int 递减
【发布时间】:2012-01-04 00:30:00
【问题描述】:

我编写了一个 iPhone 应用程序,但遇到了关于 float 和 int 之间类型转换的问题。我用 C 重写了代码,结果总是一样的,无论是在 OS X(Console 和 Xcode)、Linux(Console)还是 Windows(Visual Studio)下编译:

// Calculation of a page index depending on the amount of pages, its x-offset on the view
// and the total width of the view
#include <stdio.h>

int main()
{
    int   result   = 0;
    int   pagesCnt = 23;
    float offsetX  = 2142.0f;
    float width    = 7038.0f;

    offsetX = offsetX / width;
    offsetX = (float)pagesCnt * offsetX;
    result  = (int)offsetX;

    printf("%f (%d)\n", offsetX, result);
    // The console should show "7.000000 (7)" now
    // But actually I read "7.000000 (6)"

    return 0;
}

当然,我们这里有精度损失。使用计算器 x 进行数学运算时,结果为 7.00000000000008 而不仅仅是 7.000000。

尽管如此,就我对 C 的理解而言,这应该不是问题,因为 C 旨在在将浮点数转换为整数时截断浮点数的后点位置。在这种情况下,这就是我真正想要的。

当使用双精度而不是浮点数时,结果会如预期的那样,但我这里不需要双精度,它不应该有任何区别。

我这里有什么问题吗?在某些情况下我应该避免使用 (int) 转换为 int 吗?为什么C无论如何都会递减结果?我应该总是使用 double 吗?

非常感谢!

编辑:我误解了一些东西:当然,使用双精度而不是浮点数会有所不同。我的意思是,它不应该对 (int) 7.000000f 或 7.00000000000008 产生影响。

编辑2:多亏了你,我现在明白我的错误了。使用 printf() 而不定义浮点精度是错误的。 (int)ing 6.99... 到 6 是正确的,当然。所以,以后遇到这样的问题我会用double。

【问题讨论】:

  • 您总是可以写offsetX * pagesCnt / width 以尽可能长时间地延迟非整数值。另请注意,printf 的可变参数中存在到double 的转换。

标签: c casting floating-point int


【解决方案1】:

当我增加输出的精度时,我从你的程序收到的结果是6.99999952316284179688 (6),所以6 似乎是正确的。

【讨论】:

  • 感谢您的提示。当我评论 Daniel Fischer 的回答时,我想我现在明白了。
【解决方案2】:

如果您将printf("%f (%d)\n", offsetX, result); 更改为printf("%.8f (%d)\n", offsetX, result);,您将看到问题。进行更改后,输出为:

6.99999952 (6)

您可以通过舍入而不是强制转换为 int 来纠正此问题。即,将result = (int)offsetX; 更改为result = roundf(offsetX);。不要忘记#include &lt;math.h&gt;。现在,输出是:

6.99999952 (7)

【讨论】:

    【解决方案3】:

    在许多情况下,编译器不能随意更改浮点运算的顺序,因为有限精度算术通常不是关联的。即,

    (23 * 2142) / 7038 = 7.00000000000000000000

    (2142 / 7038) * 23 = 6.99999999999999999979

    这些不是单精度结果,但它表明双精度也不能解决您的问题。

    【讨论】:

      猜你喜欢
      • 2021-01-13
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 2012-05-10
      相关资源
      最近更新 更多