关于C++中float数据类型声明的困惑

Confusion about float data type declaration in C++

这里完全是新手。对于我的学校作业,我被要求编写一个程序来显示 -

s= 1 + 1/2 + 1/3 + 1/4 ..... + 1/n

这是我做的 -

#include<iostream.h>
#include<conio.h>

void main()
{
    clrscr();
    int a;
    float s=0, n;
    cin>>a;
    for(n=1;n<=a;n++)
    {
        s+=1/n;
    }
    cout<<s;
    getch();
}

它完美地显示了它应该显示的内容。但是,过去我只编写过使用 int 数据类型的程序。据我了解,int 数据类型不包含任何小数位,而 float 则包含。所以我对浮动还不太了解。那天晚上晚些时候,我在 YouTube 上观看了一些视频,其中他正在编写完全相同的程序,但方式略有不同。视频是外语的,所以我看不懂。他所做的被声明为 'n' 整数。

int a, n;
float s=0;

而不是

int a
float s=0, n;

但这并没有显示出想要的结果。所以他继续展示了两种纠正方法。他在 for 循环体中进行了更改 -

s+=1.0f/n;

s+=1/(float)n;

据我了解,他稍后在程序中声明了 'n' 浮点数据类型(我说得对吗?)。所以,我的问题是,两者都显示相同的结果,但两者之间有什么区别吗?因为我们声明 'n' 是一个浮点数,为什么他写了 1.0f 而不是 n.f 或 f.n。我试过了,但它给出了错误。而在第二种方法中,为什么我们不能写 1(float)/n 而不是 1/(float)n?与第一种方法一样,我们添加了带 1 的浮点数后缀。另外,1.f 和 1.0f 之间有区别吗?

我试图 google 我的问题,但找不到任何答案。此外,几个小时后我想到的另一个困惑是——为什么我们甚至要声明 'n' 浮动?根据程序,总和应该是一个实数。所以,我们不应该只声明 's' 一个浮点数。我越想我的大脑就越混乱。请帮忙!

谢谢。

原因是整数除法与浮点除法的行为不同。

4 / 3 给出整数 110 / 3 给出整数 3

然而,4.0f / 3 给你浮点数 1.3333...10.0f / 3 给你浮点数 3.3333...

所以如果你有:

float f = 4 / 3;

4 / 3 将为您提供整数 1,然后将其作为 1.0f 存储到浮点数 f 中。

相反,您必须确保除数或被除数是浮点数:

float f = 4.0f / 3;
float f = 4 / 3.0f;

如果你有两个整数变量,那么你必须先将其中一个转换为浮点数:

int a = ..., b = ...;
float f = (float)a / b;
float f = a / (float)b;

第一个相当于:

float tmp = a;
float f = tmp / b;

由于 n 永远只有一个整数值,因此将其定义为 int 是有意义的。然而,这样做意味着这不会像您预期的那样工作:

s+=1/n;

在除法运算中,两个操作数都是整数类型,所以它执行整数除法,这意味着它取结果的整数部分并丢弃任何小数部分。所以 1/2 的计算结果是 0,因为 1 除以 2 结果是 0.5,丢掉分数结果是 0。

这与保留小数部分的浮点除法形成对比。如果任一操作数是浮点类型,C 将执行浮点除法。

对于上述表达式,我们可以通过对任一操作数执行类型转换来强制进行浮点除法:

s += (float)1/n

或:

s += 1/(float)n

也可以通过给出小数部分来指定常量1为浮点常量:

s += 1.0/n

或附加 f 后缀:

s += 1.0f/n

f 后缀(以及 ULLL 后缀)只能应用于数值常量,不能应用于变量。

他做的是一种叫做选角的东西。我相信你们学校会在新的讲座中提到它。基本上 n 被设置为整个程序的整数。但是由于 integer 和 double 很相似(都是数字),所以 c/c++ 语言允许你使用它们,只要你告诉编译器你想用它做什么。您可以通过添加括号和数据类型来做到这一点,即

(float) n

he declared 'n' a float data type later in the program(Am I right?)

不,他定义(因此也声明)n 一个 int,后来他明确地将其转换(转换)为 float。两者非常不同。

both display the same result but is there any difference between the two?

没有。在这种情况下,它们是相同的。当算术运算符有 intfloat 操作数时,前者被隐式转换为后者,因此结果也将是 float。他只是向您展示了两种方法。当两个操作数都是整数时,当正确的数学除法会给你一个非整数商时,你会得到一个可能不正确的整数值。为了避免这种情况,通常将其中一个操作数做成浮点数,使实际结果更接近预期结果。

why he has written 1.0f instead of n.f or f.n. I tried it but it gives error. [...] Also, is there a difference between 1.f and 1.0f?

这是因为语言语法是这样定义的。当您声明浮点文字时,后缀是使用 .f。所以 5int5.0f5.ffloat;省略任何尾随 0 时没有区别。但是,n.f 是语法错误,因为 n 是标识符(变量)名称而不是常量数字文字。

And in the second method, why we can't write 1(float)/n instead of 1/(float)n?

(float)nint 变量 n 的有效 C 风格转换,而 1(float) 只是语法错误。

s+=1.0f/n;

and

s+=1/(float)n;

... So, my question is, both display the same result but is there any difference between the two?

是的。

在 C 和 C++ 中,当计算涉及不同类型的表达式时,这些表达式中的一个或多个将 "promoted" 为具有更高精度或范围的类型。因此,如果您有一个包含 signedunsigned 操作数的表达式,则 signed 操作数将为 "promoted" 到 unsigned。如果表达式包含 floatdouble 操作数,则 float 操作数将提升为 double

请记住,用两个整数操作数进行除法会得到一个整数结果 - 1/2 会产生 0,而不是 0.5。要获得浮点结果,至少一个操作数必须具有浮点类型。

1.0f/n 的情况下,表达式 1.0f 的类型为 float1,因此 n 将是"promoted" 从类型 int 到类型 float

1/(float) n 的情况下,表达式 n 被显式 cast 类型 float,所以表达式 1 从类型 int 提升为 float

吹毛求疵:

  • 除非您的编译器文档 明确void main() 列为 main 函数的合法签名,否则请改用 int main()。来自 online C++ standard
    3.6.1 Main function
    ...
    2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a declared return type of type int, but otherwise its type is implementation-defined...
  • 其次,格式化您的代码 - 它使其他人更容易阅读和调试。空格和缩进是你的朋友——使用它们。


1。没有后缀的常量表达式 1.0 的类型为 doublef 后缀告诉编译器将其视为 float1.0/n 会产生 double.
类型的值