如何正确将浮点数转换为int

时间:2019-04-22 00:14:06

标签: c

似乎我在投射时缺少一些基本知识,我不知道它是什么!

检查此代码:

----------------- current_i = 13.000000 ------------------
new current_i = 1.300000 
floating_part = 0.300000
float_to_int_part = 2

这里的输出是

float_to_int_part

我期望32,但是输出始终为then,这非常令人困惑。 我不知道为什么的事实意味着我错过了一些非常基本的东西,这可能意味着我缺少了一些更基本的事实。如果有人可以告诉我我的代码有什么问题,并建议一本书或一个链接(您认为会有所帮助)来填补这一空白。

对我来说,更重要的是要知道导致错误的原因。如果我所有的变量都为float,则输出正确且模块正常工作。

2 个答案:

答案 0 :(得分:2)

13F / 10不能用二进制编码的float变量精确表示。

如果尝试打印更多的小数,您将看到发生的情况:

#include <stdio.h>

int main(void) {
    float current_i;
    float floating_part;
    int float_to_int_part;

    current_i = 13;

    printf("current_i = %.16f\n", current_i);
    current_i = current_i / 10;
    printf("new current_i = %.16f\n", current_i);

    floating_part = (current_i - (int)current_i);
    printf("floating_part = %.16f\n", floating_part);

    float_to_int_part = (int)(floating_part * 10.0);
    printf("float_to_int_part = %d\n", float_to_int_part);

    return 0;
}

输出:

current_i = 13.0000000000000000
new current_i = 1.2999999523162842
floating_part = 0.2999999523162842
float_to_int_part = 2

还要注意,float的值在传递给double时会转换为printf,表达式(int)(floating_part * 10.0)是用double算术求值的,因为{{1 }}是一个10.0常量。这些值也不会精确地表示为double,但是将double转换为float会使不精确性更加明显,并且double表示的近似值小于实际值。值float,而类型为1.3的表示形式则稍大一些,因此最终转换会产生预期值:

double

输出:

#include <stdio.h>

int main(void) {
    double current_i;
    double floating_part;
    int float_to_int_part;

    current_i = 13;

    printf("current_i = %.23f\n", current_i);
    current_i = current_i / 10;
    printf("new current_i = %.23f \n", current_i);

    floating_part = (current_i - (int)current_i);
    printf("floating_part = %.23f\n", floating_part);

    float_to_int_part = (int)(floating_part * 10.0);
    printf("float_to_int_part = %d\n", float_to_int_part);

    return 0;
}

要可靠地评估这些计算,您需要对浮点值使用基于十进制的表示形式。 C标准默认不指定此类类型,而是作为Technical Report中描述的扩展名。类型current_i = 13.00000000000000000000000 new current_i = 1.30000000000000004440892 floating_part = 0.30000000000000004440892 float_to_int_part = 3 _Decimal32_Decimal64在您的系统上可能可用(例如_Decimal128selected targets上支持它们)。

答案 1 :(得分:-2)

此答案不是正确的解决方案,我不知道是否存在。如下所述,这是一个“创可贴”解决方案,因为双精度并不意味着它会在所有情况下都解决问题(只是碰巧在此问题中“解决了”)

尝试使用double而不是float。并像bolov所说的那样this

它有效here

当将(int)声明为float_to_int_part时,您也不需要int强制转换,因为它是隐式的