如何在C语言中将浮点数与整数相乘?

12

当我执行这段代码时,它返回给我1610612736

void main(){
float a=3.3f;
int b=2;
printf("%d",a*b);
}
为什么会出现这种情况,该如何解决?
编辑:这甚至不是整数和浮点数的问题,如果我将int b=2:替换为float b=2.0f,它返回相同的愚蠢结果。

这是一个关于整数和浮点数的问题 - 请看我的答案。 - Carl Norum
@Carl 是正确的。这可能不是浮点/整数问题,而是在格式化字符串中 肯定 存在问题。 - paxdiablo
函数printf是一个varargs方法,签名为int printf(const char * format, ...)。这意味着它在第一个参数后面接受任意数量的参数,并且无法在编译时检查它们或将它们从格式字符串中转换为所需类型。您的格式字符串中使用了%d,它寻找一个int。表达式a*bfloat类型,会被转换为double类型。这些类型甚至没有相同的内存大小,因此临时的double类型会被物理上分成两半并视为int类型。这不是一个明智的解决方案。 - Eric Jablow
可能是Arduino sprintf浮点数格式化不正确的重复问题。 - user177800
2个回答

19

将一个float和一个int相乘的结果是一个float。此外,当传递给printf时,它将被提升为double。你需要使用%a%e%f%g格式进行输出。而%d格式用于打印int类型。

编者注:main函数的返回值应该是int类型。以下是修正后的程序:

#include <stdio.h>

int main(void)
{
    float a = 3.3f;
    int b = 2;
    printf("%a\n", a * b);
    printf("%e\n", a * b);
    printf("%f\n", a * b);
    printf("%g\n", a * b);
    return 0;
}

以及它的输出:

$ ./example 
0x1.a66666p+2
6.600000e+00
6.600000
6.6

2
哇,%a 一定是竞争“printf角色中最无用的格式说明符”奖项的热门人选 :-) - paxdiablo
9
很棒!使用它可以通过字符串100%准确地转换(二进制)浮点数,甚至可以传递到不使用IEEE754的系统。它以完全明确的方式保留了所有位的精度。用户可能并不关心看到它…… - Carl Norum
3
那是一个我没有考虑过的使用案例,好想法。 - paxdiablo
1
第一次看到 %a!除了调试目的,我真的不觉得它有什么用处。 - Phong

4
你可以选择另一种方式,也可以这样做。
printf("%d\n", (int)(a*b));

执行这个操作会输出你期望的结果。

总是要将变量显式地进行类型转换以匹配格式字符串,否则可能会看到一些奇怪的值被打印出来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接