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

时间:2015-09-18 19:28:11

标签: c++ c

这是一个完整的新手。对于我的学校作业,我被允许编写一个显示的程序 -

  

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

这就是我做的 -

function toTitleCase(str) {
     return str.replace(/\b[a-z]/g, function (txt) { 
       return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); 
     });
}

它完美展现了应有的东西。但是,在过去我只编写了使用int数据类型的程序。据我所知,int数据类型不包含任何小数位,而浮点数。所以我对浮动还不太了解。那天晚上晚些时候,我正在观看YouTube上的一些视频,他正在编写完全相同的节目,但方式略有不同。视频是用一些外语的,所以我无法理解。他所做的是将'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 a, n;
float s=0;

但这并没有显示出理想的结果。所以他继续前进并展示了两种方法来纠正它。他在for循环体中做了改变 -

int a
float s=0, n;

s+=1.0f/n;

根据我的理解,他在程序的后期声明'n'是浮动数据类型(我是否正确?)。所以,我的问题是,两者都显示相同的结果,但两者之间有什么区别吗?当我们宣称'n'是浮点数时,为什么他写了1.0f而不是n.f或f.n.我试了但是它给出了错误。在第二种方法中,为什么我们不能写1(float)/ n而不是1 /(float)n?与第一种方法一样,我们将浮点后缀添加为1.另外,1.f和1.0f之间是否存在差异?

我试图谷歌我的问题,但找不到任何答案。此外,几个小时后出现的另一个混乱是 - 为什么我们甚至宣称'n'是浮动的?按照程序,总和应该是实数。所以,我们不应该只宣称's'是浮动的。我越想我就越混淆我的大脑。请帮忙!

谢谢。

5 个答案:

答案 0 :(得分:7)

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

4 / 3为您提供整数110 / 3为您提供整数3

但是,4.0f / 3为您提供了浮动1.3333...10.0f / 3为您提供了浮动3.3333...

所以如果你有:

float f = 4 / 3;

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

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

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;

答案 1 :(得分:3)

由于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后缀)只能应用于数字常量,而不能应用于变量。

答案 2 :(得分:1)

他正在做的事情就是铸造。我相信你的学校会在新的讲座中提到它。基本上,n被设置为整个程序的整数。但由于整数和双数相似(都是数字),c / c ++语言允许您使用它们,只要您告诉编译器您想要使用它。您可以通过添加括号和数据类型来实现此目的,即

(float) n

答案 3 :(得分:1)

  

他在程序的后期声明'n'是浮点数据类型(我是对的吗?)

不,他定义了(因此也宣称)nint,后来他明确地将其转换(铸造)为float。两者都非常不同。

  

两者都显示相同的结果,但这两者之间有什么区别吗?

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

  

为什么他写了1.0f而不是n.f或f.n.我试了但是它给出了错误。 [...]另外,1.f和1.0f之间有区别吗?

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

  

在第二种方法中,为什么我们不能写1(float)/ n而不是1 /(float)n?

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

答案 4 :(得分:1)

  

s+=1.0f/n;

     

     

s+=1/(float)n;

     

...所以,我的问题是,两者都显示相同的结果,但两者之间有什么区别吗?

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

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

对于1.0f/n,表达式1.0f的类型为float 1 ,因此n将从类型“提升” int输入float

对于1/(float) n,表达式n正在明确地强制转换float类型,因此表达式1从输入intfloat

挑剔:

  • 除非您的编译器文档明确void main()列为main函数的合法签名,否则请改用int main()。来自online C++ standard
    3.6.1主要功能
    ...
    2实现不应预定义main函数。此功能不应过载。 它应具有类型为int 的声明的返回类型,否则其类型是实现定义的...
  • 其次,格式化您的代码 - 这使其他人更容易阅读和调试。空白和缩进是你的朋友 - 使用它们。

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