英文:
Mathematical operation on macro value in C
问题
以下是程序的输出:
原程序输出为:T = 0.0000。
修改后的程序输出为:T = 0.000125。
请注意,将Fs宏定义更改为浮点变量后,输出值变为0.000125,这是因为在原始程序中,1/Fs 中的Fs是整数,所以结果会被截断为0。但是在修改后的程序中,Fs被声明为浮点数,所以除法操作得到了正确的结果。
英文:
The output of the following program is T = 0.0000.
#include <stdio.h>
#include <math.h>
#define Fs 8000
int main()
{
float T = 1/Fs;
printf("T = %f", T);
return 0;
}
However, when the macro Fs is declared as a float variable inside main, I get the correct output T = 0.000125. Can anyone explain what is going on? Is it possible to get the correct output with the macro too?
#include <stdio.h>
#include <math.h>
int main()
{
float Fs = 8000;
float T = 1/Fs;
printf("T = %f", T);
return 0;
}
答案1
得分: 1
Integer divided by integer = integer. Integer divided by float = float.
Either:
#define Fs 8000.0
and/or
float T = 1.0/Fs;
and/or
float T = 1/(float)(Fs);
英文:
Integer divided by integer = integer. Integer divided by float = float.
Either:
#define Fs 8000.0
and/or
float T = 1.0/Fs;
and/or
float T = 1/(float)(Fs);
答案2
得分: 1
以下是翻译的内容:
能否有人解释正在发生什么?
在 C 中,运算符使用的类型是基于该运算符的操作数选择的,而不是基于存储结果的类型。
此外,包括常量在内,一切都有类型。8000 的类型是 int,8000.0 的类型是 double,而 8000.0f 的类型是 float。
在使用 Fs 宏表示整数 8000 的情况下,1/Fs,那么除法的两个操作数都是 int 类型。因此,除法是在 int 类型上执行的,结果是 0。
如果使用 Fs 类型为 float 来表示 1/Fs,则除法的一个操作数是 int,另一个操作数是 float。有一种被称为 "通常的算术转换"(参见 https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules)的机制,会将 int "提升" 为 float 类型。这时除法是在 float 类型上执行的。
一些最佳实践:
- 避免将整数/
int常量与浮点运算混合使用。相反,使用纯浮点常量/变量编写涉及浮点的每个表达式。 - 处理
float时使用8000.0f,处理double时使用8000.0。 float是 C 程序中几乎不应该使用的类型,在初学者程序中根本不应使用。唯一应该使用float的情况是当 CPU 具有单精度 FPU,但不支持double精度 - 这是一个非常特定的情况,不适用于现代的 x86 PC,在这些系统中应该在所有地方使用double。- 避免编写依赖于隐式类型提升的代码。如果从一开始使用正确的类型,可以避免此类提升。
英文:
> Can anyone explain what is going on?
In C the type used by an operator is picked based on that operator's operands and not based on the type where you store the result.
Also everything including constants has a type. 8000 is type int, 8000.0 is type double and 8000.0f is type float.
In case of 1/Fs with Fs as a macro for the integer 8000, then both operands of the division are int. Therefore the division is carried out on int type and you get the result 0 because of it.
In case of 1/Fs with Fs as type float, one operand of the division is int and the other is float. Something called "the usual arithmetic conversions" (see https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules) then "promotes" the int to type float. The division is carried out on float type.
Some best practices:
- Avoid mixing integers/
intconstants with floating point arithmetic. Instead write every expression involving floating point with pure floating point constants/variables. - Use
8000.0fwhen dealing withfloatand8000.0when dealing withdouble. floatis a type that should barely ever be used in C programs and never in beginner programs. The only scenario where you should ever usefloatis when your CPU has a single precision FPU but no hardware support fordoubleprecision - which is a very specific scenario and not applicable to modern x86 PC wheredoubleshould be used everywhere.- Avoid writing code relying on implicit type promotions. If correct types are used from the start, such promotions can be avoided.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论