Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当数字变小时,long是否会将其四舍五入?_C++_Gcc - Fatal编程技术网

C++ 当数字变小时,long是否会将其四舍五入?

C++ 当数字变小时,long是否会将其四舍五入?,c++,gcc,C++,Gcc,我使用的是Manjaro 64位最新版本。HP pavilion g6,代码块 发布13.12版本9501(2013-12-25 18:25:45)gcc 5.2.0 Linux/unicode-64位 学生们讨论了原因 sn=1/n发散 sn=1/n^2收敛 所以决定写一个关于它的程序,只是为了向他们展示他们能期望得到什么样的输出 #include <iostream> #include <math.h> #include <fstream> usin

我使用的是Manjaro 64位最新版本。HP pavilion g6,代码块 发布13.12版本9501(2013-12-25 18:25:45)gcc 5.2.0 Linux/unicode-64位

学生们讨论了原因

  • sn=1/n发散
  • sn=1/n^2收敛
所以决定写一个关于它的程序,只是为了向他们展示他们能期望得到什么样的输出

#include <iostream>
#include <math.h>
#include <fstream>

using namespace std;

int main()
{
   long double sn =0, sn2=0; // sn2 is 1/n^2
   ofstream myfile;
   myfile.open("/home/Projects/c++/test/test.csv");

    for (double n =2; n<100000000;n++){
            sn += 1/n;
            sn2 += 1/pow(n,2);
            myfile << "For n = " << n << " Sn = " << sn << " and Sn2 = " << sn2 << endl;

    }

    myfile.close();
    return 0;
}   
#包括
#包括
#包括
使用名称空间std;
int main()
{
长双sn=0,sn2=0;//sn2是1/n^2
流文件;
myfile.open(“/home/Projects/c++/test/test.csv”);

对于(double n=2;n来说,您编写的代码有一个典型的编程错误:它首先将较大的数字相加,然后再将较小的数字相加,从而对浮点数序列求和

这将不可避免地导致加法过程中的精度损失,因为在序列的某个点上,和将变得相对较大,而序列的下一个成员将变得相对较小。将足够小的浮点值添加到足够大的浮点和中不会影响和。一旦达到该点,即使尝试添加的值不是零,加法操作看起来也会被“忽略”

如果在典型机器上尝试计算
100000000.0f+1
,您可以观察到同样的效果:它的计算结果仍然是
100000000
。这不会发生,因为
1
以某种方式被舍入为零。这是因为数学上正确的结果
10000001
被舍入回
100000000
。为了通过添加强制更改
100000000.0f
,您需要至少添加
5
(并且结果将“捕捉”到
10000008

因此,这里的问题并不是编译器“在它变得如此小时对数字进行舍入”,正如您似乎相信的那样。您的
1/pow(n,2)
数字可能很好并且足够精确(没有舍入到0)。这里的问题是在循环的某个迭代中,
1/pow(n,2)的小非零值
再也不能影响总和了

虽然调整输出精度确实会帮助您更好地了解正在发生的事情(如评论中所述),但真正的问题是上述内容


在计算成员大小差异较大的浮点序列的和时,应首先添加较小的序列成员。再次使用我的
100000000.0f
示例,您可以很容易地看到
4.0f+4.0f+100000000.0f
正确地生成
10000008
,而
100000000.0f+4.0f+4.0f
仍然是
100000000

这里没有遇到精度问题。总和不会停在0.644834;:

注意9!这不再是0.644834了

<>如果您预期1.644934,则应该在n=1 < /Cord>中开始求和。如果您预期连续的部分和之间出现可见的变化,则没有看到那些,因为C++将总和的表示截断为6个有效数字。可以配置输出流以显示更多的数字,并使用<代码> STD::StestPrimsion
来自
iomanip
标题:

myfile << std::setprecision(9);

<代码> MyFipe,这都是输出数字的原因。@ DavidSchwartz不适合在线。没有意义,如果第一行不适合,C++不能写在下一行上吗?输出的默认精度是6位数。如果你想看到其余的,你必须多问一些,例如:代码> cou@ bPopssAHHHHHOMSEME,我能要求它超额吗?但直到数字的末尾,不管它可能有多长?只是一个旁注:如果你真的想理解为什么一个收敛而另一个不收敛,你应该做一些数学计算。收敛/发散的定义不能用一个运行有限时间的程序来证明。这实际上不是问题。com有足够多的精度可用用简单的方法把这个总数设为6位数。OP可能只是等待的时间不够长。(此外,我可能会选择较小的数字,而不是从较小的数字开始。)这是我为数不多的几次更改公认答案的情况之一:)
0.644934
myfile << std::setprecision(9);