【问题标题】:Confusion about float data type declaration in C++关于 C++ 中浮点数据类型声明的困惑
【发布时间】:2015-09-18 19:28:10
【问题描述】:

这里是一个完整的新手。为了我的学校作业,我被要求编写一个显示 -

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' 为浮点数时,为什么他写的是 1.0f 而不是 n.f 或 f.n。我试过了,但它给出了错误。而在第二种方法中,为什么我们不能写 1(float)/n 而不是 1/(float)n?和第一种方法一样,我们添加了float后缀1。另外,1.f和1.0f有区别吗?

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

谢谢。

【问题讨论】:

  • 为了我们和您的利益,请缩进您的代码:)
  • 抱歉,我就是这样编码的。我在 HTML、CSS 和 JS 中的代码完全一样。但是,我会从下一次开始记住这一点。
  • @DevanshKumar:建议您尽早习惯缩进代码!
  • 当然,我会养成这个习惯的。

标签: c++ c


【解决方案1】:

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

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;

【讨论】:

  • 感谢您的清理。但是 tmp 是做什么用的呢?你能再解释一下吗?
  • @DevanshKumar:这只是为了展示float f = (float)a / b 的作用。取整数a,将其转换为浮点数,然后将该浮点数(刚刚从整数转换而来的)除以b。这会给你一个浮点结果(例如1.333)而不是整数结果(1)。这相当于创建一个临时浮点变量来放入a
【解决方案2】:

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

【讨论】:

  • 只是一个小问题:1.0 给出了 double 文字,而不是 float
【解决方案3】:

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

(float) n

【讨论】:

    【解决方案4】:

    他稍后在程序中声明了“n”一个浮点数据类型(我说的对吗?)

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

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

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

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

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

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

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

    【讨论】:

    • 非常感谢。现在没有混乱!
    【解决方案5】:

    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 的类型为float1,因此n 将从int 类型“提升”为float 类型.

    1/(float) n 的情况下,表达式n 被显式强制转换 类型为float,因此表达式1 从类型int 提升为float .

    挑剔:

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


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

    【讨论】:

    • 另一个很好的答案。谢谢!好吧,我问过我的老师,为什么我们使用 void main() 而不是 int main()。她说我只能使用 void main() 。稍后她将介绍 int main()。是的,我下次会记住格式。
    • @DevanshKumar:呃。当教授错误地教授语言时,我讨厌它。 C 和 C++ 语言的定义已经够怪异了,当人们把错误信息和不良做法堆在上面时,它就无济于事了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多