关于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
给出整数 1
。 10 / 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
后缀(以及 U
、L
和 LL
后缀)只能应用于数值常量,不能应用于变量。
他做的是一种叫做选角的东西。我相信你们学校会在新的讲座中提到它。基本上 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?
没有。在这种情况下,它们是相同的。当算术运算符有 int
和 float
操作数时,前者被隐式转换为后者,因此结果也将是 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
。所以 5
是 int
而 5.0f
或 5.f
是 float
;省略任何尾随 0
时没有区别。但是,n.f
是语法错误,因为 n
是标识符(变量)名称而不是常量数字文字。
And in the second method, why we can't write 1(float)/n instead of 1/(float)n?
(float)n
是 int
变量 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" 为具有更高精度或范围的类型。因此,如果您有一个包含 signed
和 unsigned
操作数的表达式,则 signed
操作数将为 "promoted" 到 unsigned
。如果表达式包含 float
和 double
操作数,则 float
操作数将提升为 double
。
请记住,用两个整数操作数进行除法会得到一个整数结果 - 1/2
会产生 0
,而不是 0.5
。要获得浮点结果,至少一个操作数必须具有浮点类型。
在 1.0f/n
的情况下,表达式 1.0f
的类型为 float
1,因此 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
的类型为 double
。 f
后缀告诉编译器将其视为 float
。 1.0/n
会产生 double
.
类型的值
这里完全是新手。对于我的学校作业,我被要求编写一个程序来显示 -
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
给出整数 1
。 10 / 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
后缀(以及 U
、L
和 LL
后缀)只能应用于数值常量,不能应用于变量。
他做的是一种叫做选角的东西。我相信你们学校会在新的讲座中提到它。基本上 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?
没有。在这种情况下,它们是相同的。当算术运算符有 int
和 float
操作数时,前者被隐式转换为后者,因此结果也将是 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
。所以 5
是 int
而 5.0f
或 5.f
是 float
;省略任何尾随 0
时没有区别。但是,n.f
是语法错误,因为 n
是标识符(变量)名称而不是常量数字文字。
And in the second method, why we can't write 1(float)/n instead of 1/(float)n?
(float)n
是 int
变量 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" 为具有更高精度或范围的类型。因此,如果您有一个包含 signed
和 unsigned
操作数的表达式,则 signed
操作数将为 "promoted" 到 unsigned
。如果表达式包含 float
和 double
操作数,则 float
操作数将提升为 double
。
请记住,用两个整数操作数进行除法会得到一个整数结果 - 1/2
会产生 0
,而不是 0.5
。要获得浮点结果,至少一个操作数必须具有浮点类型。
在 1.0f/n
的情况下,表达式 1.0f
的类型为 float
1,因此 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 themain
function. This function shall not be overloaded. It shall have a declared return type of typeint
, but otherwise its type is implementation-defined... - 其次,请格式化您的代码 - 它使其他人更容易阅读和调试。空格和缩进是你的朋友——使用它们。
1。没有后缀的常量表达式
1.0
的类型为 double
。 f
后缀告诉编译器将其视为 float
。 1.0/n
会产生 double
.类型的值