似乎我在投射时缺少一些基本知识,我不知道它是什么!
检查此代码:
----------------- current_i = 13.000000 ------------------
new current_i = 1.300000
floating_part = 0.300000
float_to_int_part = 2
这里的输出是
float_to_int_part
我期望3
为2
,但是输出始终为then
,这非常令人困惑。
我不知道为什么的事实意味着我错过了一些非常基本的东西,这可能意味着我缺少了一些更基本的事实。如果有人可以告诉我我的代码有什么问题,并建议一本书或一个链接(您认为会有所帮助)来填补这一空白。
对我来说,更重要的是要知道导致错误的原因。如果我所有的变量都为float,则输出正确且模块正常工作。
答案 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
在您的系统上可能可用(例如_Decimal128
在selected targets上支持它们)。
答案 1 :(得分:-2)