【问题标题】:What does the compiler do when it converts a float variable to an integer variable?编译器将浮点变量转换为整数变量时会做什么?
【发布时间】:2011-10-14 16:50:02
【问题描述】:

编译器是做什么的?目的是将点之后的数字作为整数。我是这样做的:

float a = 0;
cin >> a;

int b = (a - (int)a)*10;

现在我的问题是:当我输入例如 3.2 时,我得到 2,这就是我想要的。它也适用于 .4、.5 和 .7。但是当我输入例如 2.3 时,我得到 2。对于 2.7,我得到 6,依此类推。但是当我在没有变量的情况下这样做时,例如:

(2.3 - (int)2.3)*10;

我得到了正确的结果。

我不知道编译器做了什么。我一直认为,当我将浮点数转换为整数时,它会简单地切入该点。这就是我使用常量时编译器实际执行的操作。但是,当我使用变量时,编译器会减少其中的一些,但不是全部。

【问题讨论】:

  • 浮点数不精确这一事实让您感到厌烦,打印它们将舍入最小的数字,而 (int) 不进行舍入。

标签: c++ types casting floating-point int


【解决方案1】:

您的编译器很可能没有问题,但浮点数无法在二进制计算机上精确表示。

所以,当你这样做时:

float f = 2.7f;

..实际可能存储在计算机中的是:

2.6999999999999999

这是二进制计算机上浮点的一个众所周知的特性。 SO上有很多帖子讨论这个问题。

【讨论】:

    【解决方案2】:

    基本上,问题出在二进制具有与以 10 为底的值不同的“无限重复”值这一事实。例如。十进制的 1/10 是 0.1,二进制是 0.000110011001100110011001100... 问题是因为浮点数不能正确保持 2.3,因为它是无限个二进制数,但它非常接近,可能是 2.2999999。对于大多数数学来说,它已经足够接近了。但要小心截断。

    一种解决方案是在截断之前进行舍入。

    int b = (a - (int)(a+.05))*10;
    

    还要注意,浮点值在内存中的大小与在寄存器中的大小不同,这意味着在比较两个浮点值是否也相等时,您必须四舍五入。

    【讨论】:

      【解决方案3】:

      造成这种差异的原因是,默认情况下,浮点字面量是双精度值,具有更高的精度,并且能够更接近地表示您正在寻找的值。

      【讨论】:

      • 它们似乎都是 pages.cs.wisc.edu/~rkennedy/exact-float?number=2.3
      • @xanatos 你是对的。我想这是基于浮点值的舍入方式。我将从我的答案中删除第二段。
      【解决方案4】:

      你为什么不这样做呢?

      b = (a*10)%10;
      

      我觉得这要容易得多。

      【讨论】:

        猜你喜欢
        • 2010-11-24
        • 1970-01-01
        • 1970-01-01
        • 2019-04-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        • 2013-11-17
        相关资源
        最近更新 更多